mirror of
https://github.com/Ryubing/Ryujinx.git
synced 2025-03-10 17:14:25 +00:00
misc: chore: Use explicit types in Vulkan project
This commit is contained in:
parent
e6b393e420
commit
2d1a4c3ce5
@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public T GetMirrorable(CommandBufferScoped cbs, ref int offset, int size, out bool mirrored)
|
public T GetMirrorable(CommandBufferScoped cbs, ref int offset, int size, out bool mirrored)
|
||||||
{
|
{
|
||||||
var mirror = _mirrorable.GetMirrorable(cbs, ref offset, size, out mirrored);
|
Auto<T> mirror = _mirrorable.GetMirrorable(cbs, ref offset, size, out mirrored);
|
||||||
mirror._waitable?.AddBufferUse(cbs.CommandBufferIndex, offset, size, false);
|
mirror._waitable?.AddBufferUse(cbs.CommandBufferIndex, offset, size, false);
|
||||||
return mirror.Get(cbs);
|
return mirror.Get(cbs);
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
lock (_resources)
|
lock (_resources)
|
||||||
{
|
{
|
||||||
foreach (var resource in _resources.Values)
|
foreach (BackgroundResource resource in _resources.Values)
|
||||||
{
|
{
|
||||||
resource.Dispose();
|
resource.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -350,7 +350,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
// Generic pipeline memory barriers will work for desktop GPUs.
|
// Generic pipeline memory barriers will work for desktop GPUs.
|
||||||
// They do require a few more access flags on the subpass dependency, though.
|
// They do require a few more access flags on the subpass dependency, though.
|
||||||
foreach (var barrier in _imageBarriers)
|
foreach (BarrierWithStageFlags<ImageMemoryBarrier, TextureStorage> barrier in _imageBarriers)
|
||||||
{
|
{
|
||||||
_memoryBarriers.Add(new BarrierWithStageFlags<MemoryBarrier, int>(
|
_memoryBarriers.Add(new BarrierWithStageFlags<MemoryBarrier, int>(
|
||||||
barrier.Flags,
|
barrier.Flags,
|
||||||
@ -370,7 +370,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
PipelineStageFlags allFlags = PipelineStageFlags.None;
|
PipelineStageFlags allFlags = PipelineStageFlags.None;
|
||||||
|
|
||||||
foreach (var barrier in _memoryBarriers)
|
foreach (BarrierWithStageFlags<MemoryBarrier, int> barrier in _memoryBarriers)
|
||||||
{
|
{
|
||||||
allFlags |= barrier.Flags.Dest;
|
allFlags |= barrier.Flags.Dest;
|
||||||
}
|
}
|
||||||
|
@ -220,11 +220,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public BitMapStruct<T> Union(BitMapStruct<T> other)
|
public BitMapStruct<T> Union(BitMapStruct<T> other)
|
||||||
{
|
{
|
||||||
var result = new BitMapStruct<T>();
|
BitMapStruct<T> result = new BitMapStruct<T>();
|
||||||
|
|
||||||
ref var masks = ref _masks;
|
ref T masks = ref _masks;
|
||||||
ref var otherMasks = ref other._masks;
|
ref T otherMasks = ref other._masks;
|
||||||
ref var newMasks = ref result._masks;
|
ref T newMasks = ref result._masks;
|
||||||
|
|
||||||
for (int i = 0; i < masks.Length; i++)
|
for (int i = 0; i < masks.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public unsafe Auto<DisposableBufferView> CreateView(VkFormat format, int offset, int size, Action invalidateView)
|
public unsafe Auto<DisposableBufferView> CreateView(VkFormat format, int offset, int size, Action invalidateView)
|
||||||
{
|
{
|
||||||
var bufferViewCreateInfo = new BufferViewCreateInfo
|
BufferViewCreateInfo bufferViewCreateInfo = new BufferViewCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferViewCreateInfo,
|
SType = StructureType.BufferViewCreateInfo,
|
||||||
Buffer = new VkBuffer(_bufferHandle),
|
Buffer = new VkBuffer(_bufferHandle),
|
||||||
@ -122,7 +122,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Range = (uint)size,
|
Range = (uint)size,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.Api.CreateBufferView(_device, in bufferViewCreateInfo, null, out var bufferView).ThrowOnError();
|
_gd.Api.CreateBufferView(_device, in bufferViewCreateInfo, null, out BufferView bufferView).ThrowOnError();
|
||||||
|
|
||||||
return new Auto<DisposableBufferView>(new DisposableBufferView(_gd.Api, _device, bufferView), this, _waitable, _buffer);
|
return new Auto<DisposableBufferView>(new DisposableBufferView(_gd.Api, _device, bufferView), this, _waitable, _buffer);
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = ToMirrorKey(offset, size);
|
ulong key = ToMirrorKey(offset, size);
|
||||||
|
|
||||||
if (_mirrors.TryGetValue(key, out StagingBufferReserved reserved))
|
if (_mirrors.TryGetValue(key, out StagingBufferReserved reserved))
|
||||||
{
|
{
|
||||||
@ -205,14 +205,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
// Build data for the new mirror.
|
// Build data for the new mirror.
|
||||||
|
|
||||||
var baseData = new Span<byte>((void*)(_map + offset), size);
|
Span<byte> baseData = new Span<byte>((void*)(_map + offset), size);
|
||||||
var modData = _pendingData.AsSpan(offset, size);
|
Span<byte> modData = _pendingData.AsSpan(offset, size);
|
||||||
|
|
||||||
StagingBufferReserved? newMirror = _gd.BufferManager.StagingBuffer.TryReserveData(cbs, size);
|
StagingBufferReserved? newMirror = _gd.BufferManager.StagingBuffer.TryReserveData(cbs, size);
|
||||||
|
|
||||||
if (newMirror != null)
|
if (newMirror != null)
|
||||||
{
|
{
|
||||||
var mirror = newMirror.Value;
|
StagingBufferReserved mirror = newMirror.Value;
|
||||||
_pendingDataRanges.FillData(baseData, modData, offset, new Span<byte>((void*)(mirror.Buffer._map + mirror.Offset), size));
|
_pendingDataRanges.FillData(baseData, modData, offset, new Span<byte>((void*)(mirror.Buffer._map + mirror.Offset), size));
|
||||||
|
|
||||||
if (_mirrors.Count == 0)
|
if (_mirrors.Count == 0)
|
||||||
@ -319,13 +319,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void UploadPendingData(CommandBufferScoped cbs, int offset, int size)
|
private void UploadPendingData(CommandBufferScoped cbs, int offset, int size)
|
||||||
{
|
{
|
||||||
var ranges = _pendingDataRanges.FindOverlaps(offset, size);
|
List<BufferMirrorRangeList.Range> ranges = _pendingDataRanges.FindOverlaps(offset, size);
|
||||||
|
|
||||||
if (ranges != null)
|
if (ranges != null)
|
||||||
{
|
{
|
||||||
_pendingDataRanges.Remove(offset, size);
|
_pendingDataRanges.Remove(offset, size);
|
||||||
|
|
||||||
foreach (var range in ranges)
|
foreach (BufferMirrorRangeList.Range range in ranges)
|
||||||
{
|
{
|
||||||
int rangeOffset = Math.Max(offset, range.Offset);
|
int rangeOffset = Math.Max(offset, range.Offset);
|
||||||
int rangeSize = Math.Min(offset + size, range.End) - rangeOffset;
|
int rangeSize = Math.Min(offset + size, range.End) - rangeOffset;
|
||||||
@ -366,7 +366,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public BufferHandle GetHandle()
|
public BufferHandle GetHandle()
|
||||||
{
|
{
|
||||||
var handle = _bufferHandle;
|
ulong handle = _bufferHandle;
|
||||||
return Unsafe.As<ulong, BufferHandle>(ref handle);
|
return Unsafe.As<ulong, BufferHandle>(ref handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +403,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (_flushFence != null)
|
if (_flushFence != null)
|
||||||
{
|
{
|
||||||
var fence = _flushFence;
|
FenceHolder fence = _flushFence;
|
||||||
Interlocked.Increment(ref _flushWaiting);
|
Interlocked.Increment(ref _flushWaiting);
|
||||||
|
|
||||||
// Don't wait in the lock.
|
// Don't wait in the lock.
|
||||||
@ -481,7 +481,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public bool RemoveOverlappingMirrors(int offset, int size)
|
public bool RemoveOverlappingMirrors(int offset, int size)
|
||||||
{
|
{
|
||||||
List<ulong> toRemove = null;
|
List<ulong> toRemove = null;
|
||||||
foreach (var key in _mirrors.Keys)
|
foreach (ulong key in _mirrors.Keys)
|
||||||
{
|
{
|
||||||
(int keyOffset, int keySize) = FromMirrorKey(key);
|
(int keyOffset, int keySize) = FromMirrorKey(key);
|
||||||
if (!(offset + size <= keyOffset || offset >= keyOffset + keySize))
|
if (!(offset + size <= keyOffset || offset >= keyOffset + keySize))
|
||||||
@ -494,7 +494,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (toRemove != null)
|
if (toRemove != null)
|
||||||
{
|
{
|
||||||
foreach (var key in toRemove)
|
foreach (ulong key in toRemove)
|
||||||
{
|
{
|
||||||
_mirrors.Remove(key);
|
_mirrors.Remove(key);
|
||||||
}
|
}
|
||||||
@ -606,8 +606,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
BufferHolder srcHolder = _gd.BufferManager.Create(_gd, dataSize, baseType: BufferAllocationType.HostMapped);
|
BufferHolder srcHolder = _gd.BufferManager.Create(_gd, dataSize, baseType: BufferAllocationType.HostMapped);
|
||||||
srcHolder.SetDataUnchecked(0, data);
|
srcHolder.SetDataUnchecked(0, data);
|
||||||
|
|
||||||
var srcBuffer = srcHolder.GetBuffer();
|
Auto<DisposableBuffer> srcBuffer = srcHolder.GetBuffer();
|
||||||
var dstBuffer = this.GetBuffer(cbs.Value.CommandBuffer, true);
|
Auto<DisposableBuffer> dstBuffer = this.GetBuffer(cbs.Value.CommandBuffer, true);
|
||||||
|
|
||||||
Copy(_gd, cbs.Value, srcBuffer, dstBuffer, 0, offset, dataSize);
|
Copy(_gd, cbs.Value, srcBuffer, dstBuffer, 0, offset, dataSize);
|
||||||
|
|
||||||
@ -662,7 +662,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
endRenderPass?.Invoke();
|
endRenderPass?.Invoke();
|
||||||
|
|
||||||
var dstBuffer = GetBuffer(cbs.CommandBuffer, dstOffset, data.Length, true).Get(cbs, dstOffset, data.Length, true).Value;
|
VkBuffer dstBuffer = GetBuffer(cbs.CommandBuffer, dstOffset, data.Length, true).Get(cbs, dstOffset, data.Length, true).Value;
|
||||||
|
|
||||||
InsertBufferBarrier(
|
InsertBufferBarrier(
|
||||||
_gd,
|
_gd,
|
||||||
@ -709,8 +709,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int size,
|
int size,
|
||||||
bool registerSrcUsage = true)
|
bool registerSrcUsage = true)
|
||||||
{
|
{
|
||||||
var srcBuffer = registerSrcUsage ? src.Get(cbs, srcOffset, size).Value : src.GetUnsafe().Value;
|
VkBuffer srcBuffer = registerSrcUsage ? src.Get(cbs, srcOffset, size).Value : src.GetUnsafe().Value;
|
||||||
var dstBuffer = dst.Get(cbs, dstOffset, size, true).Value;
|
VkBuffer dstBuffer = dst.Get(cbs, dstOffset, size, true).Value;
|
||||||
|
|
||||||
InsertBufferBarrier(
|
InsertBufferBarrier(
|
||||||
gd,
|
gd,
|
||||||
@ -723,7 +723,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dstOffset,
|
dstOffset,
|
||||||
size);
|
size);
|
||||||
|
|
||||||
var region = new BufferCopy((ulong)srcOffset, (ulong)dstOffset, (ulong)size);
|
BufferCopy region = new BufferCopy((ulong)srcOffset, (ulong)dstOffset, (ulong)size);
|
||||||
|
|
||||||
gd.Api.CmdCopyBuffer(cbs.CommandBuffer, srcBuffer, dstBuffer, 1, ®ion);
|
gd.Api.CmdCopyBuffer(cbs.CommandBuffer, srcBuffer, dstBuffer, 1, ®ion);
|
||||||
|
|
||||||
@ -804,9 +804,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = new I8ToI16CacheKey(_gd);
|
I8ToI16CacheKey key = new I8ToI16CacheKey(_gd);
|
||||||
|
|
||||||
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out var holder))
|
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
holder = _gd.BufferManager.Create(_gd, (size * 2 + 3) & ~3, baseType: BufferAllocationType.DeviceLocal);
|
holder = _gd.BufferManager.Create(_gd, (size * 2 + 3) & ~3, baseType: BufferAllocationType.DeviceLocal);
|
||||||
|
|
||||||
@ -828,9 +828,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = new AlignedVertexBufferCacheKey(_gd, stride, alignment);
|
AlignedVertexBufferCacheKey key = new AlignedVertexBufferCacheKey(_gd, stride, alignment);
|
||||||
|
|
||||||
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out var holder))
|
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
int alignedStride = (stride + (alignment - 1)) & -alignment;
|
int alignedStride = (stride + (alignment - 1)) & -alignment;
|
||||||
|
|
||||||
@ -854,9 +854,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = new TopologyConversionCacheKey(_gd, pattern, indexSize);
|
TopologyConversionCacheKey key = new TopologyConversionCacheKey(_gd, pattern, indexSize);
|
||||||
|
|
||||||
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out var holder))
|
if (!_cachedConvertedBuffers.TryGetValue(offset, size, key, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
// The destination index size is always I32.
|
// The destination index size is always I32.
|
||||||
|
|
||||||
|
@ -96,20 +96,20 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public unsafe BufferHandle CreateHostImported(VulkanRenderer gd, nint pointer, int size)
|
public unsafe BufferHandle CreateHostImported(VulkanRenderer gd, nint pointer, int size)
|
||||||
{
|
{
|
||||||
var usage = HostImportedBufferUsageFlags;
|
BufferUsageFlags usage = HostImportedBufferUsageFlags;
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsIndirectParameters)
|
if (gd.Capabilities.SupportsIndirectParameters)
|
||||||
{
|
{
|
||||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var externalMemoryBuffer = new ExternalMemoryBufferCreateInfo
|
ExternalMemoryBufferCreateInfo externalMemoryBuffer = new ExternalMemoryBufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ExternalMemoryBufferCreateInfo,
|
SType = StructureType.ExternalMemoryBufferCreateInfo,
|
||||||
HandleTypes = ExternalMemoryHandleTypeFlags.HostAllocationBitExt,
|
HandleTypes = ExternalMemoryHandleTypeFlags.HostAllocationBitExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
var bufferCreateInfo = new BufferCreateInfo
|
BufferCreateInfo bufferCreateInfo = new BufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferCreateInfo,
|
SType = StructureType.BufferCreateInfo,
|
||||||
Size = (ulong)size,
|
Size = (ulong)size,
|
||||||
@ -118,13 +118,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PNext = &externalMemoryBuffer,
|
PNext = &externalMemoryBuffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out VkBuffer buffer).ThrowOnError();
|
||||||
|
|
||||||
(Auto<MemoryAllocation> allocation, ulong offset) = gd.HostMemoryAllocator.GetExistingAllocation(pointer, (ulong)size);
|
(Auto<MemoryAllocation> allocation, ulong offset) = gd.HostMemoryAllocator.GetExistingAllocation(pointer, (ulong)size);
|
||||||
|
|
||||||
gd.Api.BindBufferMemory(_device, buffer, allocation.GetUnsafe().Memory, allocation.GetUnsafe().Offset + offset);
|
gd.Api.BindBufferMemory(_device, buffer, allocation.GetUnsafe().Memory, allocation.GetUnsafe().Offset + offset);
|
||||||
|
|
||||||
var holder = new BufferHolder(gd, _device, buffer, allocation, size, BufferAllocationType.HostMapped, BufferAllocationType.HostMapped, (int)offset);
|
BufferHolder holder = new BufferHolder(gd, _device, buffer, allocation, size, BufferAllocationType.HostMapped, BufferAllocationType.HostMapped, (int)offset);
|
||||||
|
|
||||||
BufferCount++;
|
BufferCount++;
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public unsafe BufferHandle CreateSparse(VulkanRenderer gd, ReadOnlySpan<BufferRange> storageBuffers)
|
public unsafe BufferHandle CreateSparse(VulkanRenderer gd, ReadOnlySpan<BufferRange> storageBuffers)
|
||||||
{
|
{
|
||||||
var usage = DefaultBufferUsageFlags;
|
BufferUsageFlags usage = DefaultBufferUsageFlags;
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsIndirectParameters)
|
if (gd.Capabilities.SupportsIndirectParameters)
|
||||||
{
|
{
|
||||||
@ -149,7 +149,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
size += (ulong)range.Size;
|
size += (ulong)range.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferCreateInfo = new BufferCreateInfo()
|
BufferCreateInfo bufferCreateInfo = new BufferCreateInfo()
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferCreateInfo,
|
SType = StructureType.BufferCreateInfo,
|
||||||
Size = size,
|
Size = size,
|
||||||
@ -158,10 +158,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Flags = BufferCreateFlags.SparseBindingBit | BufferCreateFlags.SparseAliasedBit
|
Flags = BufferCreateFlags.SparseBindingBit | BufferCreateFlags.SparseAliasedBit
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out VkBuffer buffer).ThrowOnError();
|
||||||
|
|
||||||
var memoryBinds = new SparseMemoryBind[storageBuffers.Length];
|
SparseMemoryBind[] memoryBinds = new SparseMemoryBind[storageBuffers.Length];
|
||||||
var storageAllocations = new Auto<MemoryAllocation>[storageBuffers.Length];
|
Auto<MemoryAllocation>[] storageAllocations = new Auto<MemoryAllocation>[storageBuffers.Length];
|
||||||
int storageAllocationsCount = 0;
|
int storageAllocationsCount = 0;
|
||||||
|
|
||||||
ulong dstOffset = 0;
|
ulong dstOffset = 0;
|
||||||
@ -170,9 +170,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
BufferRange range = storageBuffers[index];
|
BufferRange range = storageBuffers[index];
|
||||||
|
|
||||||
if (TryGetBuffer(range.Handle, out var existingHolder))
|
if (TryGetBuffer(range.Handle, out BufferHolder existingHolder))
|
||||||
{
|
{
|
||||||
(var memory, var offset) = existingHolder.GetDeviceMemoryAndOffset();
|
(DeviceMemory memory, ulong offset) = existingHolder.GetDeviceMemoryAndOffset();
|
||||||
|
|
||||||
memoryBinds[index] = new SparseMemoryBind()
|
memoryBinds[index] = new SparseMemoryBind()
|
||||||
{
|
{
|
||||||
@ -224,7 +224,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
gd.Api.QueueBindSparse(gd.Queue, 1, in bindSparseInfo, default).ThrowOnError();
|
gd.Api.QueueBindSparse(gd.Queue, 1, in bindSparseInfo, default).ThrowOnError();
|
||||||
}
|
}
|
||||||
|
|
||||||
var holder = new BufferHolder(gd, _device, buffer, (int)size, storageAllocations);
|
BufferHolder holder = new BufferHolder(gd, _device, buffer, (int)size, storageAllocations);
|
||||||
|
|
||||||
BufferCount++;
|
BufferCount++;
|
||||||
|
|
||||||
@ -288,14 +288,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public unsafe MemoryRequirements GetHostImportedUsageRequirements(VulkanRenderer gd)
|
public unsafe MemoryRequirements GetHostImportedUsageRequirements(VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
var usage = HostImportedBufferUsageFlags;
|
BufferUsageFlags usage = HostImportedBufferUsageFlags;
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsIndirectParameters)
|
if (gd.Capabilities.SupportsIndirectParameters)
|
||||||
{
|
{
|
||||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferCreateInfo = new BufferCreateInfo
|
BufferCreateInfo bufferCreateInfo = new BufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferCreateInfo,
|
SType = StructureType.BufferCreateInfo,
|
||||||
Size = (ulong)Environment.SystemPageSize,
|
Size = (ulong)Environment.SystemPageSize,
|
||||||
@ -303,9 +303,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SharingMode = SharingMode.Exclusive,
|
SharingMode = SharingMode.Exclusive,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out VkBuffer buffer).ThrowOnError();
|
||||||
|
|
||||||
gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements);
|
gd.Api.GetBufferMemoryRequirements(_device, buffer, out MemoryRequirements requirements);
|
||||||
|
|
||||||
gd.Api.DestroyBuffer(_device, buffer, null);
|
gd.Api.DestroyBuffer(_device, buffer, null);
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
bool sparseCompatible = false,
|
bool sparseCompatible = false,
|
||||||
BufferAllocationType fallbackType = BufferAllocationType.Auto)
|
BufferAllocationType fallbackType = BufferAllocationType.Auto)
|
||||||
{
|
{
|
||||||
var usage = DefaultBufferUsageFlags;
|
BufferUsageFlags usage = DefaultBufferUsageFlags;
|
||||||
|
|
||||||
if (forConditionalRendering && gd.Capabilities.SupportsConditionalRendering)
|
if (forConditionalRendering && gd.Capabilities.SupportsConditionalRendering)
|
||||||
{
|
{
|
||||||
@ -331,7 +331,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferCreateInfo = new BufferCreateInfo
|
BufferCreateInfo bufferCreateInfo = new BufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferCreateInfo,
|
SType = StructureType.BufferCreateInfo,
|
||||||
Size = (ulong)size,
|
Size = (ulong)size,
|
||||||
@ -339,8 +339,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SharingMode = SharingMode.Exclusive,
|
SharingMode = SharingMode.Exclusive,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out VkBuffer buffer).ThrowOnError();
|
||||||
gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements);
|
gd.Api.GetBufferMemoryRequirements(_device, buffer, out MemoryRequirements requirements);
|
||||||
|
|
||||||
if (sparseCompatible)
|
if (sparseCompatible)
|
||||||
{
|
{
|
||||||
@ -351,7 +351,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
var allocateFlags = type switch
|
MemoryPropertyFlags allocateFlags = type switch
|
||||||
{
|
{
|
||||||
BufferAllocationType.HostMappedNoCache => DefaultBufferMemoryNoCacheFlags,
|
BufferAllocationType.HostMappedNoCache => DefaultBufferMemoryNoCacheFlags,
|
||||||
BufferAllocationType.HostMapped => DefaultBufferMemoryFlags,
|
BufferAllocationType.HostMapped => DefaultBufferMemoryFlags,
|
||||||
@ -402,7 +402,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (buffer.Handle != 0)
|
if (buffer.Handle != 0)
|
||||||
{
|
{
|
||||||
var holder = new BufferHolder(gd, _device, buffer, allocation, size, baseType, resultType);
|
BufferHolder holder = new BufferHolder(gd, _device, buffer, allocation, size, baseType, resultType);
|
||||||
|
|
||||||
return holder;
|
return holder;
|
||||||
}
|
}
|
||||||
@ -414,7 +414,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DisposableBufferView> CreateView(BufferHandle handle, VkFormat format, int offset, int size, Action invalidateView)
|
public Auto<DisposableBufferView> CreateView(BufferHandle handle, VkFormat format, int offset, int size, Action invalidateView)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
return holder.CreateView(format, offset, size, invalidateView);
|
return holder.CreateView(format, offset, size, invalidateView);
|
||||||
}
|
}
|
||||||
@ -424,7 +424,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DisposableBuffer> GetBuffer(CommandBuffer commandBuffer, BufferHandle handle, bool isWrite, bool isSSBO = false)
|
public Auto<DisposableBuffer> GetBuffer(CommandBuffer commandBuffer, BufferHandle handle, bool isWrite, bool isSSBO = false)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
return holder.GetBuffer(commandBuffer, isWrite, isSSBO);
|
return holder.GetBuffer(commandBuffer, isWrite, isSSBO);
|
||||||
}
|
}
|
||||||
@ -434,7 +434,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DisposableBuffer> GetBuffer(CommandBuffer commandBuffer, BufferHandle handle, int offset, int size, bool isWrite)
|
public Auto<DisposableBuffer> GetBuffer(CommandBuffer commandBuffer, BufferHandle handle, int offset, int size, bool isWrite)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
return holder.GetBuffer(commandBuffer, offset, size, isWrite);
|
return holder.GetBuffer(commandBuffer, offset, size, isWrite);
|
||||||
}
|
}
|
||||||
@ -444,7 +444,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DisposableBuffer> GetBufferI8ToI16(CommandBufferScoped cbs, BufferHandle handle, int offset, int size)
|
public Auto<DisposableBuffer> GetBufferI8ToI16(CommandBufferScoped cbs, BufferHandle handle, int offset, int size)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
return holder.GetBufferI8ToI16(cbs, offset, size);
|
return holder.GetBufferI8ToI16(cbs, offset, size);
|
||||||
}
|
}
|
||||||
@ -454,7 +454,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DisposableBuffer> GetAlignedVertexBuffer(CommandBufferScoped cbs, BufferHandle handle, int offset, int size, int stride, int alignment)
|
public Auto<DisposableBuffer> GetAlignedVertexBuffer(CommandBufferScoped cbs, BufferHandle handle, int offset, int size, int stride, int alignment)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
return holder.GetAlignedVertexBuffer(cbs, offset, size, stride, alignment);
|
return holder.GetAlignedVertexBuffer(cbs, offset, size, stride, alignment);
|
||||||
}
|
}
|
||||||
@ -464,7 +464,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DisposableBuffer> GetBufferTopologyConversion(CommandBufferScoped cbs, BufferHandle handle, int offset, int size, IndexBufferPattern pattern, int indexSize)
|
public Auto<DisposableBuffer> GetBufferTopologyConversion(CommandBufferScoped cbs, BufferHandle handle, int offset, int size, IndexBufferPattern pattern, int indexSize)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
return holder.GetBufferTopologyConversion(cbs, offset, size, pattern, indexSize);
|
return holder.GetBufferTopologyConversion(cbs, offset, size, pattern, indexSize);
|
||||||
}
|
}
|
||||||
@ -486,14 +486,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
BufferHolder drawCountBufferHolder = null;
|
BufferHolder drawCountBufferHolder = null;
|
||||||
|
|
||||||
if (!TryGetBuffer(indexBuffer.Handle, out var indexBufferHolder) ||
|
if (!TryGetBuffer(indexBuffer.Handle, out BufferHolder indexBufferHolder) ||
|
||||||
!TryGetBuffer(indirectBuffer.Handle, out var indirectBufferHolder) ||
|
!TryGetBuffer(indirectBuffer.Handle, out BufferHolder indirectBufferHolder) ||
|
||||||
(hasDrawCount && !TryGetBuffer(drawCountBuffer.Handle, out drawCountBufferHolder)))
|
(hasDrawCount && !TryGetBuffer(drawCountBuffer.Handle, out drawCountBufferHolder)))
|
||||||
{
|
{
|
||||||
return (null, null);
|
return (null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var indexBufferKey = new TopologyConversionIndirectCacheKey(
|
TopologyConversionIndirectCacheKey indexBufferKey = new TopologyConversionIndirectCacheKey(
|
||||||
gd,
|
gd,
|
||||||
pattern,
|
pattern,
|
||||||
indexSize,
|
indexSize,
|
||||||
@ -505,16 +505,16 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
indexBuffer.Offset,
|
indexBuffer.Offset,
|
||||||
indexBuffer.Size,
|
indexBuffer.Size,
|
||||||
indexBufferKey,
|
indexBufferKey,
|
||||||
out var convertedIndexBuffer);
|
out BufferHolder convertedIndexBuffer);
|
||||||
|
|
||||||
var indirectBufferKey = new IndirectDataCacheKey(pattern);
|
IndirectDataCacheKey indirectBufferKey = new IndirectDataCacheKey(pattern);
|
||||||
bool hasConvertedIndirectBuffer = indirectBufferHolder.TryGetCachedConvertedBuffer(
|
bool hasConvertedIndirectBuffer = indirectBufferHolder.TryGetCachedConvertedBuffer(
|
||||||
indirectBuffer.Offset,
|
indirectBuffer.Offset,
|
||||||
indirectBuffer.Size,
|
indirectBuffer.Size,
|
||||||
indirectBufferKey,
|
indirectBufferKey,
|
||||||
out var convertedIndirectBuffer);
|
out BufferHolder convertedIndirectBuffer);
|
||||||
|
|
||||||
var drawCountBufferKey = new DrawCountCacheKey();
|
DrawCountCacheKey drawCountBufferKey = new DrawCountCacheKey();
|
||||||
bool hasCachedDrawCount = true;
|
bool hasCachedDrawCount = true;
|
||||||
|
|
||||||
if (hasDrawCount)
|
if (hasDrawCount)
|
||||||
@ -568,7 +568,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// Any modification of the indirect buffer should invalidate the index buffers that are associated with it,
|
// Any modification of the indirect buffer should invalidate the index buffers that are associated with it,
|
||||||
// since we used the indirect data to find the range of the index buffer that is used.
|
// since we used the indirect data to find the range of the index buffer that is used.
|
||||||
|
|
||||||
var indexBufferDependency = new Dependency(
|
Dependency indexBufferDependency = new Dependency(
|
||||||
indexBufferHolder,
|
indexBufferHolder,
|
||||||
indexBuffer.Offset,
|
indexBuffer.Offset,
|
||||||
indexBuffer.Size,
|
indexBuffer.Size,
|
||||||
@ -590,7 +590,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// If we have a draw count, any modification of the draw count should invalidate all indirect buffers
|
// If we have a draw count, any modification of the draw count should invalidate all indirect buffers
|
||||||
// where we used it to find the range of indirect data that is actually used.
|
// where we used it to find the range of indirect data that is actually used.
|
||||||
|
|
||||||
var indirectBufferDependency = new Dependency(
|
Dependency indirectBufferDependency = new Dependency(
|
||||||
indirectBufferHolder,
|
indirectBufferHolder,
|
||||||
indirectBuffer.Offset,
|
indirectBuffer.Offset,
|
||||||
indirectBuffer.Size,
|
indirectBuffer.Size,
|
||||||
@ -609,7 +609,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DisposableBuffer> GetBuffer(CommandBuffer commandBuffer, BufferHandle handle, bool isWrite, out int size)
|
public Auto<DisposableBuffer> GetBuffer(CommandBuffer commandBuffer, BufferHandle handle, bool isWrite, out int size)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
size = holder.Size;
|
size = holder.Size;
|
||||||
return holder.GetBuffer(commandBuffer, isWrite);
|
return holder.GetBuffer(commandBuffer, isWrite);
|
||||||
@ -621,7 +621,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public PinnedSpan<byte> GetData(BufferHandle handle, int offset, int size)
|
public PinnedSpan<byte> GetData(BufferHandle handle, int offset, int size)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
return holder.GetData(offset, size);
|
return holder.GetData(offset, size);
|
||||||
}
|
}
|
||||||
@ -636,7 +636,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void SetData(BufferHandle handle, int offset, ReadOnlySpan<byte> data, CommandBufferScoped? cbs, Action endRenderPass)
|
public void SetData(BufferHandle handle, int offset, ReadOnlySpan<byte> data, CommandBufferScoped? cbs, Action endRenderPass)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
holder.SetData(offset, data, cbs, endRenderPass);
|
holder.SetData(offset, data, cbs, endRenderPass);
|
||||||
}
|
}
|
||||||
@ -644,7 +644,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void Delete(BufferHandle handle)
|
public void Delete(BufferHandle handle)
|
||||||
{
|
{
|
||||||
if (TryGetBuffer(handle, out var holder))
|
if (TryGetBuffer(handle, out BufferHolder holder))
|
||||||
{
|
{
|
||||||
holder.Dispose();
|
holder.Dispose();
|
||||||
_buffers.Remove((int)Unsafe.As<BufferHandle, ulong>(ref handle));
|
_buffers.Remove((int)Unsafe.As<BufferHandle, ulong>(ref handle));
|
||||||
|
@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public readonly bool Remove(int offset, int size)
|
public readonly bool Remove(int offset, int size)
|
||||||
{
|
{
|
||||||
var list = _ranges;
|
List<Range> list = _ranges;
|
||||||
bool removedAny = false;
|
bool removedAny = false;
|
||||||
if (list != null)
|
if (list != null)
|
||||||
{
|
{
|
||||||
@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int endOffset = offset + size;
|
int endOffset = offset + size;
|
||||||
int startIndex = overlapIndex;
|
int startIndex = overlapIndex;
|
||||||
|
|
||||||
var currentOverlap = list[overlapIndex];
|
Range currentOverlap = list[overlapIndex];
|
||||||
|
|
||||||
// Orphan the start of the overlap.
|
// Orphan the start of the overlap.
|
||||||
if (currentOverlap.Offset < offset)
|
if (currentOverlap.Offset < offset)
|
||||||
@ -102,7 +102,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void Add(int offset, int size)
|
public void Add(int offset, int size)
|
||||||
{
|
{
|
||||||
var list = _ranges;
|
List<Range> list = _ranges;
|
||||||
if (list != null)
|
if (list != null)
|
||||||
{
|
{
|
||||||
int overlapIndex = BinarySearch(list, offset, size);
|
int overlapIndex = BinarySearch(list, offset, size);
|
||||||
@ -118,8 +118,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
while (overlapIndex < list.Count && list[overlapIndex].OverlapsWith(offset, size))
|
while (overlapIndex < list.Count && list[overlapIndex].OverlapsWith(offset, size))
|
||||||
{
|
{
|
||||||
var currentOverlap = list[overlapIndex];
|
Range currentOverlap = list[overlapIndex];
|
||||||
var currentOverlapEndOffset = currentOverlap.Offset + currentOverlap.Size;
|
int currentOverlapEndOffset = currentOverlap.Offset + currentOverlap.Size;
|
||||||
|
|
||||||
if (offset > currentOverlap.Offset)
|
if (offset > currentOverlap.Offset)
|
||||||
{
|
{
|
||||||
@ -159,7 +159,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public readonly bool OverlapsWith(int offset, int size)
|
public readonly bool OverlapsWith(int offset, int size)
|
||||||
{
|
{
|
||||||
var list = _ranges;
|
List<Range> list = _ranges;
|
||||||
if (list == null)
|
if (list == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -170,7 +170,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public readonly List<Range> FindOverlaps(int offset, int size)
|
public readonly List<Range> FindOverlaps(int offset, int size)
|
||||||
{
|
{
|
||||||
var list = _ranges;
|
List<Range> list = _ranges;
|
||||||
if (list == null)
|
if (list == null)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@ -208,7 +208,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
int middle = left + (range >> 1);
|
int middle = left + (range >> 1);
|
||||||
|
|
||||||
var item = list[middle];
|
Range item = list[middle];
|
||||||
|
|
||||||
if (item.OverlapsWith(offset, size))
|
if (item.OverlapsWith(offset, size))
|
||||||
{
|
{
|
||||||
@ -233,7 +233,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int size = baseData.Length;
|
int size = baseData.Length;
|
||||||
int endOffset = offset + size;
|
int endOffset = offset + size;
|
||||||
|
|
||||||
var list = _ranges;
|
List<Range> list = _ranges;
|
||||||
if (list == null)
|
if (list == null)
|
||||||
{
|
{
|
||||||
baseData.CopyTo(result);
|
baseData.CopyTo(result);
|
||||||
@ -245,7 +245,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < list.Count; i++)
|
for (int i = 0; i < list.Count; i++)
|
||||||
{
|
{
|
||||||
var range = list[i];
|
Range range = list[i];
|
||||||
|
|
||||||
int rangeEnd = range.Offset + range.Size;
|
int rangeEnd = range.Offset + range.Size;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
@ -23,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (_buffer != null)
|
if (_buffer != null)
|
||||||
{
|
{
|
||||||
var buffer = _buffer.Get(cbs, _offset, _size, true).Value;
|
Buffer buffer = _buffer.Get(cbs, _offset, _size, true).Value;
|
||||||
|
|
||||||
ulong offset = (ulong)_offset;
|
ulong offset = (ulong)_offset;
|
||||||
ulong size = (ulong)_size;
|
ulong size = (ulong)_size;
|
||||||
|
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void Initialize(Vk api, Device device, CommandPool pool)
|
public void Initialize(Vk api, Device device, CommandPool pool)
|
||||||
{
|
{
|
||||||
var allocateInfo = new CommandBufferAllocateInfo
|
CommandBufferAllocateInfo allocateInfo = new CommandBufferAllocateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.CommandBufferAllocateInfo,
|
SType = StructureType.CommandBufferAllocateInfo,
|
||||||
CommandBufferCount = 1,
|
CommandBufferCount = 1,
|
||||||
@ -75,7 +75,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_concurrentFenceWaitUnsupported = concurrentFenceWaitUnsupported;
|
_concurrentFenceWaitUnsupported = concurrentFenceWaitUnsupported;
|
||||||
_owner = Thread.CurrentThread;
|
_owner = Thread.CurrentThread;
|
||||||
|
|
||||||
var commandPoolCreateInfo = new CommandPoolCreateInfo
|
CommandPoolCreateInfo commandPoolCreateInfo = new CommandPoolCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.CommandPoolCreateInfo,
|
SType = StructureType.CommandPoolCreateInfo,
|
||||||
QueueFamilyIndex = queueFamilyIndex,
|
QueueFamilyIndex = queueFamilyIndex,
|
||||||
@ -114,7 +114,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _totalCommandBuffers; i++)
|
for (int i = 0; i < _totalCommandBuffers; i++)
|
||||||
{
|
{
|
||||||
ref var entry = ref _commandBuffers[i];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[i];
|
||||||
|
|
||||||
if (entry.InConsumption)
|
if (entry.InConsumption)
|
||||||
{
|
{
|
||||||
@ -130,7 +130,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _totalCommandBuffers; i++)
|
for (int i = 0; i < _totalCommandBuffers; i++)
|
||||||
{
|
{
|
||||||
ref var entry = ref _commandBuffers[i];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[i];
|
||||||
|
|
||||||
if (entry.InUse)
|
if (entry.InUse)
|
||||||
{
|
{
|
||||||
@ -142,7 +142,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void AddWaitable(int cbIndex, MultiFenceHolder waitable)
|
public void AddWaitable(int cbIndex, MultiFenceHolder waitable)
|
||||||
{
|
{
|
||||||
ref var entry = ref _commandBuffers[cbIndex];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex];
|
||||||
if (waitable.AddFence(cbIndex, entry.Fence))
|
if (waitable.AddFence(cbIndex, entry.Fence))
|
||||||
{
|
{
|
||||||
entry.Waitables.Add(waitable);
|
entry.Waitables.Add(waitable);
|
||||||
@ -155,7 +155,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _totalCommandBuffers; i++)
|
for (int i = 0; i < _totalCommandBuffers; i++)
|
||||||
{
|
{
|
||||||
ref var entry = ref _commandBuffers[i];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[i];
|
||||||
|
|
||||||
if (entry.InUse &&
|
if (entry.InUse &&
|
||||||
waitable.HasFence(i) &&
|
waitable.HasFence(i) &&
|
||||||
@ -175,7 +175,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _totalCommandBuffers; i++)
|
for (int i = 0; i < _totalCommandBuffers; i++)
|
||||||
{
|
{
|
||||||
ref var entry = ref _commandBuffers[i];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[i];
|
||||||
|
|
||||||
if (entry.InUse && entry.Fence == fence)
|
if (entry.InUse && entry.Fence == fence)
|
||||||
{
|
{
|
||||||
@ -205,7 +205,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
int index = _queuedIndexes[_queuedIndexesPtr];
|
int index = _queuedIndexes[_queuedIndexesPtr];
|
||||||
|
|
||||||
ref var entry = ref _commandBuffers[index];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[index];
|
||||||
|
|
||||||
if (wait || !entry.InConsumption || entry.Fence.IsSignaled())
|
if (wait || !entry.InConsumption || entry.Fence.IsSignaled())
|
||||||
{
|
{
|
||||||
@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < _totalCommandBuffers; i++)
|
for (int i = 0; i < _totalCommandBuffers; i++)
|
||||||
{
|
{
|
||||||
ref var entry = ref _commandBuffers[cursor];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[cursor];
|
||||||
|
|
||||||
if (!entry.InUse && !entry.InConsumption)
|
if (!entry.InUse && !entry.InConsumption)
|
||||||
{
|
{
|
||||||
@ -248,7 +248,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_inUseCount++;
|
_inUseCount++;
|
||||||
|
|
||||||
var commandBufferBeginInfo = new CommandBufferBeginInfo
|
CommandBufferBeginInfo commandBufferBeginInfo = new CommandBufferBeginInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.CommandBufferBeginInfo,
|
SType = StructureType.CommandBufferBeginInfo,
|
||||||
};
|
};
|
||||||
@ -280,7 +280,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
int cbIndex = cbs.CommandBufferIndex;
|
int cbIndex = cbs.CommandBufferIndex;
|
||||||
|
|
||||||
ref var entry = ref _commandBuffers[cbIndex];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex];
|
||||||
|
|
||||||
Debug.Assert(entry.InUse);
|
Debug.Assert(entry.InUse);
|
||||||
Debug.Assert(entry.CommandBuffer.Handle == cbs.CommandBuffer.Handle);
|
Debug.Assert(entry.CommandBuffer.Handle == cbs.CommandBuffer.Handle);
|
||||||
@ -289,7 +289,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
entry.SubmissionCount++;
|
entry.SubmissionCount++;
|
||||||
_inUseCount--;
|
_inUseCount--;
|
||||||
|
|
||||||
var commandBuffer = entry.CommandBuffer;
|
CommandBuffer commandBuffer = entry.CommandBuffer;
|
||||||
|
|
||||||
_api.EndCommandBuffer(commandBuffer).ThrowOnError();
|
_api.EndCommandBuffer(commandBuffer).ThrowOnError();
|
||||||
|
|
||||||
@ -324,7 +324,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void WaitAndDecrementRef(int cbIndex, bool refreshFence = true)
|
private void WaitAndDecrementRef(int cbIndex, bool refreshFence = true)
|
||||||
{
|
{
|
||||||
ref var entry = ref _commandBuffers[cbIndex];
|
ref ReservedCommandBuffer entry = ref _commandBuffers[cbIndex];
|
||||||
|
|
||||||
if (entry.InConsumption)
|
if (entry.InConsumption)
|
||||||
{
|
{
|
||||||
@ -332,12 +332,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
entry.InConsumption = false;
|
entry.InConsumption = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var dependant in entry.Dependants)
|
foreach (IAuto dependant in entry.Dependants)
|
||||||
{
|
{
|
||||||
dependant.DecrementReferenceCount(cbIndex);
|
dependant.DecrementReferenceCount(cbIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var waitable in entry.Waitables)
|
foreach (MultiFenceHolder waitable in entry.Waitables)
|
||||||
{
|
{
|
||||||
waitable.RemoveFence(cbIndex);
|
waitable.RemoveFence(cbIndex);
|
||||||
waitable.RemoveBufferUses(cbIndex);
|
waitable.RemoveBufferUses(cbIndex);
|
||||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (bufferInfo.Buffer.Handle != 0UL)
|
if (bufferInfo.Buffer.Handle != 0UL)
|
||||||
{
|
{
|
||||||
var writeDescriptorSet = new WriteDescriptorSet
|
WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet
|
||||||
{
|
{
|
||||||
SType = StructureType.WriteDescriptorSet,
|
SType = StructureType.WriteDescriptorSet,
|
||||||
DstSet = _descriptorSets[setIndex],
|
DstSet = _descriptorSets[setIndex],
|
||||||
@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
fixed (DescriptorBufferInfo* pBufferInfo = bufferInfo)
|
fixed (DescriptorBufferInfo* pBufferInfo = bufferInfo)
|
||||||
{
|
{
|
||||||
var writeDescriptorSet = new WriteDescriptorSet
|
WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet
|
||||||
{
|
{
|
||||||
SType = StructureType.WriteDescriptorSet,
|
SType = StructureType.WriteDescriptorSet,
|
||||||
DstSet = _descriptorSets[setIndex],
|
DstSet = _descriptorSets[setIndex],
|
||||||
@ -74,7 +74,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (imageInfo.ImageView.Handle != 0UL)
|
if (imageInfo.ImageView.Handle != 0UL)
|
||||||
{
|
{
|
||||||
var writeDescriptorSet = new WriteDescriptorSet
|
WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet
|
||||||
{
|
{
|
||||||
SType = StructureType.WriteDescriptorSet,
|
SType = StructureType.WriteDescriptorSet,
|
||||||
DstSet = _descriptorSets[setIndex],
|
DstSet = _descriptorSets[setIndex],
|
||||||
@ -97,7 +97,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
fixed (DescriptorImageInfo* pImageInfo = imageInfo)
|
fixed (DescriptorImageInfo* pImageInfo = imageInfo)
|
||||||
{
|
{
|
||||||
var writeDescriptorSet = new WriteDescriptorSet
|
WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet
|
||||||
{
|
{
|
||||||
SType = StructureType.WriteDescriptorSet,
|
SType = StructureType.WriteDescriptorSet,
|
||||||
DstSet = _descriptorSets[setIndex],
|
DstSet = _descriptorSets[setIndex],
|
||||||
@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var writeDescriptorSet = new WriteDescriptorSet
|
WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet
|
||||||
{
|
{
|
||||||
SType = StructureType.WriteDescriptorSet,
|
SType = StructureType.WriteDescriptorSet,
|
||||||
DstSet = _descriptorSets[setIndex],
|
DstSet = _descriptorSets[setIndex],
|
||||||
@ -156,7 +156,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (texelBufferView.Handle != 0UL)
|
if (texelBufferView.Handle != 0UL)
|
||||||
{
|
{
|
||||||
var writeDescriptorSet = new WriteDescriptorSet
|
WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet
|
||||||
{
|
{
|
||||||
SType = StructureType.WriteDescriptorSet,
|
SType = StructureType.WriteDescriptorSet,
|
||||||
DstSet = _descriptorSets[setIndex],
|
DstSet = _descriptorSets[setIndex],
|
||||||
@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
var writeDescriptorSet = new WriteDescriptorSet
|
WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet
|
||||||
{
|
{
|
||||||
SType = StructureType.WriteDescriptorSet,
|
SType = StructureType.WriteDescriptorSet,
|
||||||
DstSet = _descriptorSets[setIndex],
|
DstSet = _descriptorSets[setIndex],
|
||||||
|
@ -24,14 +24,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Api = api;
|
Api = api;
|
||||||
Device = device;
|
Device = device;
|
||||||
|
|
||||||
foreach (var poolSize in poolSizes)
|
foreach (DescriptorPoolSize poolSize in poolSizes)
|
||||||
{
|
{
|
||||||
_freeDescriptors += (int)poolSize.DescriptorCount;
|
_freeDescriptors += (int)poolSize.DescriptorCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed (DescriptorPoolSize* pPoolsSize = poolSizes)
|
fixed (DescriptorPoolSize* pPoolsSize = poolSizes)
|
||||||
{
|
{
|
||||||
var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo
|
DescriptorPoolCreateInfo descriptorPoolCreateInfo = new DescriptorPoolCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DescriptorPoolCreateInfo,
|
SType = StructureType.DescriptorPoolCreateInfo,
|
||||||
Flags = updateAfterBind ? DescriptorPoolCreateFlags.UpdateAfterBindBit : DescriptorPoolCreateFlags.None,
|
Flags = updateAfterBind ? DescriptorPoolCreateFlags.UpdateAfterBindBit : DescriptorPoolCreateFlags.None,
|
||||||
@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public unsafe DescriptorSetCollection AllocateDescriptorSets(ReadOnlySpan<DescriptorSetLayout> layouts, int consumedDescriptors)
|
public unsafe DescriptorSetCollection AllocateDescriptorSets(ReadOnlySpan<DescriptorSetLayout> layouts, int consumedDescriptors)
|
||||||
{
|
{
|
||||||
TryAllocateDescriptorSets(layouts, consumedDescriptors, isTry: false, out var dsc);
|
TryAllocateDescriptorSets(layouts, consumedDescriptors, isTry: false, out DescriptorSetCollection dsc);
|
||||||
return dsc;
|
return dsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
fixed (DescriptorSetLayout* pLayouts = layouts)
|
fixed (DescriptorSetLayout* pLayouts = layouts)
|
||||||
{
|
{
|
||||||
var descriptorSetAllocateInfo = new DescriptorSetAllocateInfo
|
DescriptorSetAllocateInfo descriptorSetAllocateInfo = new DescriptorSetAllocateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DescriptorSetAllocateInfo,
|
SType = StructureType.DescriptorSetAllocateInfo,
|
||||||
DescriptorPool = _pool,
|
DescriptorPool = _pool,
|
||||||
@ -77,7 +77,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PSetLayouts = pLayouts,
|
PSetLayouts = pLayouts,
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = Api.AllocateDescriptorSets(Device, &descriptorSetAllocateInfo, pDescriptorSets);
|
Result result = Api.AllocateDescriptorSets(Device, &descriptorSetAllocateInfo, pDescriptorSets);
|
||||||
if (isTry && result == Result.ErrorOutOfPoolMemory)
|
if (isTry && result == Result.ErrorOutOfPoolMemory)
|
||||||
{
|
{
|
||||||
_totalSets = (int)MaxSets;
|
_totalSets = (int)MaxSets;
|
||||||
@ -182,8 +182,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
// If we fail the first time, just create a new pool and try again.
|
// If we fail the first time, just create a new pool and try again.
|
||||||
|
|
||||||
var pool = GetPool(api, poolSizes, poolIndex, layouts.Length, consumedDescriptors, updateAfterBind);
|
DescriptorPoolHolder pool = GetPool(api, poolSizes, poolIndex, layouts.Length, consumedDescriptors, updateAfterBind);
|
||||||
if (!pool.TryAllocateDescriptorSets(layouts, consumedDescriptors, out var dsc))
|
if (!pool.TryAllocateDescriptorSets(layouts, consumedDescriptors, out DescriptorSetCollection dsc))
|
||||||
{
|
{
|
||||||
pool = GetPool(api, poolSizes, poolIndex, layouts.Length, consumedDescriptors, updateAfterBind);
|
pool = GetPool(api, poolSizes, poolIndex, layouts.Length, consumedDescriptors, updateAfterBind);
|
||||||
dsc = pool.AllocateDescriptorSets(layouts, consumedDescriptors);
|
dsc = pool.AllocateDescriptorSets(layouts, consumedDescriptors);
|
||||||
|
@ -86,7 +86,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Size = (int)structureOffset;
|
Size = (int)structureOffset;
|
||||||
|
|
||||||
var info = new DescriptorUpdateTemplateCreateInfo()
|
DescriptorUpdateTemplateCreateInfo info = new DescriptorUpdateTemplateCreateInfo()
|
||||||
{
|
{
|
||||||
SType = StructureType.DescriptorUpdateTemplateCreateInfo,
|
SType = StructureType.DescriptorUpdateTemplateCreateInfo,
|
||||||
DescriptorUpdateEntryCount = (uint)segments.Length,
|
DescriptorUpdateEntryCount = (uint)segments.Length,
|
||||||
@ -173,7 +173,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Size = (int)structureOffset;
|
Size = (int)structureOffset;
|
||||||
|
|
||||||
var info = new DescriptorUpdateTemplateCreateInfo()
|
DescriptorUpdateTemplateCreateInfo info = new DescriptorUpdateTemplateCreateInfo()
|
||||||
{
|
{
|
||||||
SType = StructureType.DescriptorUpdateTemplateCreateInfo,
|
SType = StructureType.DescriptorUpdateTemplateCreateInfo,
|
||||||
DescriptorUpdateEntryCount = (uint)entry,
|
DescriptorUpdateEntryCount = (uint)entry,
|
||||||
|
@ -7,6 +7,7 @@ using System.Buffers;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||||
using Format = Ryujinx.Graphics.GAL.Format;
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||||
@ -156,7 +157,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_uniformSetPd = new int[Constants.MaxUniformBufferBindings];
|
_uniformSetPd = new int[Constants.MaxUniformBufferBindings];
|
||||||
|
|
||||||
var initialImageInfo = new DescriptorImageInfo
|
DescriptorImageInfo initialImageInfo = new DescriptorImageInfo
|
||||||
{
|
{
|
||||||
ImageLayout = ImageLayout.General,
|
ImageLayout = ImageLayout.General,
|
||||||
};
|
};
|
||||||
@ -301,13 +302,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < segment.Count; i++)
|
for (int i = 0; i < segment.Count; i++)
|
||||||
{
|
{
|
||||||
ref var texture = ref _textureRefs[segment.Binding + i];
|
ref TextureRef texture = ref _textureRefs[segment.Binding + i];
|
||||||
texture.View?.PrepareForUsage(cbs, texture.Stage.ConvertToPipelineStageFlags(), FeedbackLoopHazards);
|
texture.View?.PrepareForUsage(cbs, texture.Stage.ConvertToPipelineStageFlags(), FeedbackLoopHazards);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ref var arrayRef = ref _textureArrayRefs[segment.Binding];
|
ref ArrayRef<TextureArray> arrayRef = ref _textureArrayRefs[segment.Binding];
|
||||||
PipelineStageFlags stageFlags = arrayRef.Stage.ConvertToPipelineStageFlags();
|
PipelineStageFlags stageFlags = arrayRef.Stage.ConvertToPipelineStageFlags();
|
||||||
arrayRef.Array?.QueueWriteToReadBarriers(cbs, stageFlags);
|
arrayRef.Array?.QueueWriteToReadBarriers(cbs, stageFlags);
|
||||||
}
|
}
|
||||||
@ -322,13 +323,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < segment.Count; i++)
|
for (int i = 0; i < segment.Count; i++)
|
||||||
{
|
{
|
||||||
ref var image = ref _imageRefs[segment.Binding + i];
|
ref ImageRef image = ref _imageRefs[segment.Binding + i];
|
||||||
image.View?.PrepareForUsage(cbs, image.Stage.ConvertToPipelineStageFlags(), FeedbackLoopHazards);
|
image.View?.PrepareForUsage(cbs, image.Stage.ConvertToPipelineStageFlags(), FeedbackLoopHazards);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ref var arrayRef = ref _imageArrayRefs[segment.Binding];
|
ref ArrayRef<ImageArray> arrayRef = ref _imageArrayRefs[segment.Binding];
|
||||||
PipelineStageFlags stageFlags = arrayRef.Stage.ConvertToPipelineStageFlags();
|
PipelineStageFlags stageFlags = arrayRef.Stage.ConvertToPipelineStageFlags();
|
||||||
arrayRef.Array?.QueueWriteToReadBarriers(cbs, stageFlags);
|
arrayRef.Array?.QueueWriteToReadBarriers(cbs, stageFlags);
|
||||||
}
|
}
|
||||||
@ -337,7 +338,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int setIndex = PipelineBase.DescriptorSetLayouts; setIndex < _program.BindingSegments.Length; setIndex++)
|
for (int setIndex = PipelineBase.DescriptorSetLayouts; setIndex < _program.BindingSegments.Length; setIndex++)
|
||||||
{
|
{
|
||||||
var bindingSegments = _program.BindingSegments[setIndex];
|
ResourceBindingSegment[] bindingSegments = _program.BindingSegments[setIndex];
|
||||||
|
|
||||||
if (bindingSegments.Length == 0)
|
if (bindingSegments.Length == 0)
|
||||||
{
|
{
|
||||||
@ -353,13 +354,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
segment.Type == ResourceType.TextureAndSampler ||
|
segment.Type == ResourceType.TextureAndSampler ||
|
||||||
segment.Type == ResourceType.BufferTexture)
|
segment.Type == ResourceType.BufferTexture)
|
||||||
{
|
{
|
||||||
ref var arrayRef = ref _textureArrayExtraRefs[setIndex - PipelineBase.DescriptorSetLayouts];
|
ref ArrayRef<TextureArray> arrayRef = ref _textureArrayExtraRefs[setIndex - PipelineBase.DescriptorSetLayouts];
|
||||||
PipelineStageFlags stageFlags = arrayRef.Stage.ConvertToPipelineStageFlags();
|
PipelineStageFlags stageFlags = arrayRef.Stage.ConvertToPipelineStageFlags();
|
||||||
arrayRef.Array?.QueueWriteToReadBarriers(cbs, stageFlags);
|
arrayRef.Array?.QueueWriteToReadBarriers(cbs, stageFlags);
|
||||||
}
|
}
|
||||||
else if (segment.Type == ResourceType.Image || segment.Type == ResourceType.BufferImage)
|
else if (segment.Type == ResourceType.Image || segment.Type == ResourceType.BufferImage)
|
||||||
{
|
{
|
||||||
ref var arrayRef = ref _imageArrayExtraRefs[setIndex - PipelineBase.DescriptorSetLayouts];
|
ref ArrayRef<ImageArray> arrayRef = ref _imageArrayExtraRefs[setIndex - PipelineBase.DescriptorSetLayouts];
|
||||||
PipelineStageFlags stageFlags = arrayRef.Stage.ConvertToPipelineStageFlags();
|
PipelineStageFlags stageFlags = arrayRef.Stage.ConvertToPipelineStageFlags();
|
||||||
arrayRef.Array?.QueueWriteToReadBarriers(cbs, stageFlags);
|
arrayRef.Array?.QueueWriteToReadBarriers(cbs, stageFlags);
|
||||||
}
|
}
|
||||||
@ -424,8 +425,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < buffers.Length; i++)
|
for (int i = 0; i < buffers.Length; i++)
|
||||||
{
|
{
|
||||||
var assignment = buffers[i];
|
BufferAssignment assignment = buffers[i];
|
||||||
var buffer = assignment.Range;
|
BufferRange buffer = assignment.Range;
|
||||||
int index = assignment.Binding;
|
int index = assignment.Binding;
|
||||||
|
|
||||||
Auto<DisposableBuffer> vkBuffer = buffer.Handle == BufferHandle.Null
|
Auto<DisposableBuffer> vkBuffer = buffer.Handle == BufferHandle.Null
|
||||||
@ -440,7 +441,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Range = (ulong)buffer.Size,
|
Range = (ulong)buffer.Size,
|
||||||
};
|
};
|
||||||
|
|
||||||
var newRef = new BufferRef(vkBuffer, ref buffer);
|
BufferRef newRef = new BufferRef(vkBuffer, ref buffer);
|
||||||
|
|
||||||
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
||||||
|
|
||||||
@ -460,7 +461,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < buffers.Length; i++)
|
for (int i = 0; i < buffers.Length; i++)
|
||||||
{
|
{
|
||||||
var vkBuffer = buffers[i];
|
Auto<DisposableBuffer> vkBuffer = buffers[i];
|
||||||
int index = first + i;
|
int index = first + i;
|
||||||
|
|
||||||
ref BufferRef currentBufferRef = ref _storageBufferRefs[index];
|
ref BufferRef currentBufferRef = ref _storageBufferRefs[index];
|
||||||
@ -633,8 +634,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < buffers.Length; i++)
|
for (int i = 0; i < buffers.Length; i++)
|
||||||
{
|
{
|
||||||
var assignment = buffers[i];
|
BufferAssignment assignment = buffers[i];
|
||||||
var buffer = assignment.Range;
|
BufferRange buffer = assignment.Range;
|
||||||
int index = assignment.Binding;
|
int index = assignment.Binding;
|
||||||
|
|
||||||
Auto<DisposableBuffer> vkBuffer = buffer.Handle == BufferHandle.Null
|
Auto<DisposableBuffer> vkBuffer = buffer.Handle == BufferHandle.Null
|
||||||
@ -678,7 +679,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var program = _program;
|
ShaderCollection program = _program;
|
||||||
|
|
||||||
if (_dirty.HasFlag(DirtyFlags.Uniform))
|
if (_dirty.HasFlag(DirtyFlags.Uniform))
|
||||||
{
|
{
|
||||||
@ -760,14 +761,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void UpdateAndBind(CommandBufferScoped cbs, ShaderCollection program, int setIndex, PipelineBindPoint pbp)
|
private void UpdateAndBind(CommandBufferScoped cbs, ShaderCollection program, int setIndex, PipelineBindPoint pbp)
|
||||||
{
|
{
|
||||||
var bindingSegments = program.BindingSegments[setIndex];
|
ResourceBindingSegment[] bindingSegments = program.BindingSegments[setIndex];
|
||||||
|
|
||||||
if (bindingSegments.Length == 0)
|
if (bindingSegments.Length == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dummyBuffer = _dummyBuffer?.GetBuffer();
|
Auto<DisposableBuffer> dummyBuffer = _dummyBuffer?.GetBuffer();
|
||||||
|
|
||||||
if (_updateDescriptorCacheCbIndex)
|
if (_updateDescriptorCacheCbIndex)
|
||||||
{
|
{
|
||||||
@ -775,7 +776,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
program.UpdateDescriptorCacheCommandBufferIndex(cbs.CommandBufferIndex);
|
program.UpdateDescriptorCacheCommandBufferIndex(cbs.CommandBufferIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dsc = program.GetNewDescriptorSetCollection(setIndex, out var isNew).Get(cbs);
|
DescriptorSetCollection dsc = program.GetNewDescriptorSetCollection(setIndex, out bool isNew).Get(cbs);
|
||||||
|
|
||||||
if (!program.HasMinimalLayout)
|
if (!program.HasMinimalLayout)
|
||||||
{
|
{
|
||||||
@ -824,7 +825,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (_storageSet.Set(index))
|
if (_storageSet.Set(index))
|
||||||
{
|
{
|
||||||
ref var info = ref _storageBuffers[index];
|
ref DescriptorBufferInfo info = ref _storageBuffers[index];
|
||||||
|
|
||||||
bool mirrored = UpdateBuffer(cbs,
|
bool mirrored = UpdateBuffer(cbs,
|
||||||
ref info,
|
ref info,
|
||||||
@ -850,8 +851,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ref var texture = ref textures[i];
|
ref DescriptorImageInfo texture = ref textures[i];
|
||||||
ref var refs = ref _textureRefs[binding + i];
|
ref TextureRef refs = ref _textureRefs[binding + i];
|
||||||
|
|
||||||
texture.ImageView = refs.ImageView?.Get(cbs).Value ?? default;
|
texture.ImageView = refs.ImageView?.Get(cbs).Value ?? default;
|
||||||
texture.Sampler = refs.Sampler?.Get(cbs).Value ?? default;
|
texture.Sampler = refs.Sampler?.Get(cbs).Value ?? default;
|
||||||
@ -934,7 +935,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var sets = dsc.GetSets();
|
DescriptorSet[] sets = dsc.GetSets();
|
||||||
_templateUpdater.Commit(_gd, _device, sets[0]);
|
_templateUpdater.Commit(_gd, _device, sets[0]);
|
||||||
|
|
||||||
_gd.Api.CmdBindDescriptorSets(cbs.CommandBuffer, pbp, _program.PipelineLayout, (uint)setIndex, 1, sets, 0, ReadOnlySpan<uint>.Empty);
|
_gd.Api.CmdBindDescriptorSets(cbs.CommandBuffer, pbp, _program.PipelineLayout, (uint)setIndex, 1, sets, 0, ReadOnlySpan<uint>.Empty);
|
||||||
@ -943,7 +944,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private void UpdateAndBindTexturesWithoutTemplate(CommandBufferScoped cbs, ShaderCollection program, PipelineBindPoint pbp)
|
private void UpdateAndBindTexturesWithoutTemplate(CommandBufferScoped cbs, ShaderCollection program, PipelineBindPoint pbp)
|
||||||
{
|
{
|
||||||
int setIndex = PipelineBase.TextureSetIndex;
|
int setIndex = PipelineBase.TextureSetIndex;
|
||||||
var bindingSegments = program.BindingSegments[setIndex];
|
ResourceBindingSegment[] bindingSegments = program.BindingSegments[setIndex];
|
||||||
|
|
||||||
if (bindingSegments.Length == 0)
|
if (bindingSegments.Length == 0)
|
||||||
{
|
{
|
||||||
@ -956,7 +957,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
program.UpdateDescriptorCacheCommandBufferIndex(cbs.CommandBufferIndex);
|
program.UpdateDescriptorCacheCommandBufferIndex(cbs.CommandBufferIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dsc = program.GetNewDescriptorSetCollection(setIndex, out _).Get(cbs);
|
DescriptorSetCollection dsc = program.GetNewDescriptorSetCollection(setIndex, out _).Get(cbs);
|
||||||
|
|
||||||
foreach (ResourceBindingSegment segment in bindingSegments)
|
foreach (ResourceBindingSegment segment in bindingSegments)
|
||||||
{
|
{
|
||||||
@ -971,8 +972,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ref var texture = ref textures[i];
|
ref DescriptorImageInfo texture = ref textures[i];
|
||||||
ref var refs = ref _textureRefs[binding + i];
|
ref TextureRef refs = ref _textureRefs[binding + i];
|
||||||
|
|
||||||
texture.ImageView = refs.ImageView?.Get(cbs).Value ?? default;
|
texture.ImageView = refs.ImageView?.Get(cbs).Value ?? default;
|
||||||
texture.Sampler = refs.Sampler?.Get(cbs).Value ?? default;
|
texture.Sampler = refs.Sampler?.Get(cbs).Value ?? default;
|
||||||
@ -1015,7 +1016,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var sets = dsc.GetSets();
|
DescriptorSet[] sets = dsc.GetSets();
|
||||||
|
|
||||||
_gd.Api.CmdBindDescriptorSets(cbs.CommandBuffer, pbp, _program.PipelineLayout, (uint)setIndex, 1, sets, 0, ReadOnlySpan<uint>.Empty);
|
_gd.Api.CmdBindDescriptorSets(cbs.CommandBuffer, pbp, _program.PipelineLayout, (uint)setIndex, 1, sets, 0, ReadOnlySpan<uint>.Empty);
|
||||||
}
|
}
|
||||||
@ -1024,8 +1025,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private void UpdateAndBindUniformBufferPd(CommandBufferScoped cbs)
|
private void UpdateAndBindUniformBufferPd(CommandBufferScoped cbs)
|
||||||
{
|
{
|
||||||
int sequence = _pdSequence;
|
int sequence = _pdSequence;
|
||||||
var bindingSegments = _program.BindingSegments[PipelineBase.UniformSetIndex];
|
ResourceBindingSegment[] bindingSegments = _program.BindingSegments[PipelineBase.UniformSetIndex];
|
||||||
var dummyBuffer = _dummyBuffer?.GetBuffer();
|
Auto<DisposableBuffer> dummyBuffer = _dummyBuffer?.GetBuffer();
|
||||||
|
|
||||||
long updatedBindings = 0;
|
long updatedBindings = 0;
|
||||||
DescriptorSetTemplateWriter writer = _templateUpdater.Begin(32 * Unsafe.SizeOf<DescriptorBufferInfo>());
|
DescriptorSetTemplateWriter writer = _templateUpdater.Begin(32 * Unsafe.SizeOf<DescriptorBufferInfo>());
|
||||||
@ -1077,7 +1078,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
|
Buffer dummyBuffer = _dummyBuffer?.GetBuffer().Get(cbs).Value ?? default;
|
||||||
|
|
||||||
foreach (ResourceBindingSegment segment in _program.ClearSegments[setIndex])
|
foreach (ResourceBindingSegment segment in _program.ClearSegments[setIndex])
|
||||||
{
|
{
|
||||||
@ -1089,7 +1090,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int setIndex = PipelineBase.DescriptorSetLayouts; setIndex < program.BindingSegments.Length; setIndex++)
|
for (int setIndex = PipelineBase.DescriptorSetLayouts; setIndex < program.BindingSegments.Length; setIndex++)
|
||||||
{
|
{
|
||||||
var bindingSegments = program.BindingSegments[setIndex];
|
ResourceBindingSegment[] bindingSegments = program.BindingSegments[setIndex];
|
||||||
|
|
||||||
if (bindingSegments.Length == 0)
|
if (bindingSegments.Length == 0)
|
||||||
{
|
{
|
||||||
|
@ -41,9 +41,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
|
|
||||||
_pipeline.Initialize();
|
_pipeline.Initialize();
|
||||||
|
|
||||||
var scalingShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/AreaScaling.spv");
|
byte[] scalingShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/AreaScaling.spv");
|
||||||
|
|
||||||
var scalingResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout scalingResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
||||||
@ -83,7 +83,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
};
|
};
|
||||||
|
|
||||||
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
||||||
using var buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize);
|
using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize);
|
||||||
buffer.Holder.SetDataUnchecked(buffer.Offset, dimensionsBuffer);
|
buffer.Holder.SetDataUnchecked(buffer.Offset, dimensionsBuffer);
|
||||||
|
|
||||||
int threadGroupWorkRegionDim = 16;
|
int threadGroupWorkRegionDim = 16;
|
||||||
|
@ -53,15 +53,15 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
|
|
||||||
_pipeline.Initialize();
|
_pipeline.Initialize();
|
||||||
|
|
||||||
var scalingShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrScaling.spv");
|
byte[] scalingShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrScaling.spv");
|
||||||
var sharpeningShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrSharpening.spv");
|
byte[] sharpeningShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/FsrSharpening.spv");
|
||||||
|
|
||||||
var scalingResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout scalingResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
||||||
|
|
||||||
var sharpeningResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout sharpeningResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 3)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 3)
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 4)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 4)
|
||||||
@ -96,9 +96,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
|| _intermediaryTexture.Info.Height != height
|
|| _intermediaryTexture.Info.Height != height
|
||||||
|| !_intermediaryTexture.Info.Equals(view.Info))
|
|| !_intermediaryTexture.Info.Equals(view.Info))
|
||||||
{
|
{
|
||||||
var originalInfo = view.Info;
|
TextureCreateInfo originalInfo = view.Info;
|
||||||
|
|
||||||
var info = new TextureCreateInfo(
|
TextureCreateInfo info = new TextureCreateInfo(
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
originalInfo.Depth,
|
originalInfo.Depth,
|
||||||
@ -142,11 +142,11 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
};
|
};
|
||||||
|
|
||||||
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
||||||
using var buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize);
|
using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize);
|
||||||
buffer.Holder.SetDataUnchecked(buffer.Offset, dimensionsBuffer);
|
buffer.Holder.SetDataUnchecked(buffer.Offset, dimensionsBuffer);
|
||||||
|
|
||||||
ReadOnlySpan<float> sharpeningBufferData = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f) };
|
ReadOnlySpan<float> sharpeningBufferData = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f) };
|
||||||
using var sharpeningBuffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, sizeof(float));
|
using ScopedTemporaryBuffer sharpeningBuffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, sizeof(float));
|
||||||
sharpeningBuffer.Holder.SetDataUnchecked(sharpeningBuffer.Offset, sharpeningBufferData);
|
sharpeningBuffer.Holder.SetDataUnchecked(sharpeningBuffer.Offset, sharpeningBufferData);
|
||||||
|
|
||||||
int threadGroupWorkRegionDim = 16;
|
int threadGroupWorkRegionDim = 16;
|
||||||
|
@ -37,9 +37,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
{
|
{
|
||||||
_pipeline.Initialize();
|
_pipeline.Initialize();
|
||||||
|
|
||||||
var shader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/Fxaa.spv");
|
byte[] shader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/Fxaa.spv");
|
||||||
|
|
||||||
var resourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout resourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
||||||
@ -66,14 +66,14 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
|
|
||||||
ReadOnlySpan<float> resolutionBuffer = stackalloc float[] { view.Width, view.Height };
|
ReadOnlySpan<float> resolutionBuffer = stackalloc float[] { view.Width, view.Height };
|
||||||
int rangeSize = resolutionBuffer.Length * sizeof(float);
|
int rangeSize = resolutionBuffer.Length * sizeof(float);
|
||||||
using var buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize);
|
using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked(buffer.Offset, resolutionBuffer);
|
buffer.Holder.SetDataUnchecked(buffer.Offset, resolutionBuffer);
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, buffer.Range) });
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, buffer.Range) });
|
||||||
|
|
||||||
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
int dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
||||||
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
int dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
||||||
|
|
||||||
_pipeline.SetImage(ShaderStage.Compute, 0, _texture.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
_pipeline.SetImage(ShaderStage.Compute, 0, _texture.GetView(FormatTable.ConvertRgba8SrgbToUnorm(view.Info.Format)));
|
||||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
@ -74,23 +75,23 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
|
|
||||||
_pipeline.Initialize();
|
_pipeline.Initialize();
|
||||||
|
|
||||||
var edgeShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaEdge.spv");
|
byte[] edgeShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaEdge.spv");
|
||||||
var blendShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaBlend.spv");
|
byte[] blendShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaBlend.spv");
|
||||||
var neighbourShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaNeighbour.spv");
|
byte[] neighbourShader = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Shaders/SmaaNeighbour.spv");
|
||||||
|
|
||||||
var edgeResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout edgeResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
||||||
|
|
||||||
var blendResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout blendResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 3)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 3)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 4)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 4)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
||||||
|
|
||||||
var neighbourResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout neighbourResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 2)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 3)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 3)
|
||||||
@ -108,7 +109,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
QualityUltra = Quality == 3 ? 1 : 0,
|
QualityUltra = Quality == 3 ? 1 : 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
var specInfo = new SpecDescription(
|
SpecDescription specInfo = new SpecDescription(
|
||||||
(0, SpecConstType.Int32),
|
(0, SpecConstType.Int32),
|
||||||
(1, SpecConstType.Int32),
|
(1, SpecConstType.Int32),
|
||||||
(2, SpecConstType.Int32),
|
(2, SpecConstType.Int32),
|
||||||
@ -142,7 +143,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
var areaInfo = new TextureCreateInfo(AreaWidth,
|
TextureCreateInfo areaInfo = new TextureCreateInfo(AreaWidth,
|
||||||
AreaHeight,
|
AreaHeight,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
@ -158,7 +159,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
SwizzleComponent.Blue,
|
SwizzleComponent.Blue,
|
||||||
SwizzleComponent.Alpha);
|
SwizzleComponent.Alpha);
|
||||||
|
|
||||||
var searchInfo = new TextureCreateInfo(SearchWidth,
|
TextureCreateInfo searchInfo = new TextureCreateInfo(SearchWidth,
|
||||||
SearchHeight,
|
SearchHeight,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
@ -174,8 +175,8 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
SwizzleComponent.Blue,
|
SwizzleComponent.Blue,
|
||||||
SwizzleComponent.Alpha);
|
SwizzleComponent.Alpha);
|
||||||
|
|
||||||
var areaTexture = EmbeddedResources.ReadFileToRentedMemory("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaAreaTexture.bin");
|
MemoryOwner<byte> areaTexture = EmbeddedResources.ReadFileToRentedMemory("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaAreaTexture.bin");
|
||||||
var searchTexture = EmbeddedResources.ReadFileToRentedMemory("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaSearchTexture.bin");
|
MemoryOwner<byte> searchTexture = EmbeddedResources.ReadFileToRentedMemory("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaSearchTexture.bin");
|
||||||
|
|
||||||
_areaTexture = _renderer.CreateTexture(areaInfo) as TextureView;
|
_areaTexture = _renderer.CreateTexture(areaInfo) as TextureView;
|
||||||
_searchTexture = _renderer.CreateTexture(searchInfo) as TextureView;
|
_searchTexture = _renderer.CreateTexture(searchInfo) as TextureView;
|
||||||
@ -205,8 +206,8 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
|
|
||||||
_renderer.Pipeline.TextureBarrier();
|
_renderer.Pipeline.TextureBarrier();
|
||||||
|
|
||||||
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
int dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
||||||
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
int dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
||||||
|
|
||||||
// Edge pass
|
// Edge pass
|
||||||
_pipeline.SetProgram(_edgeProgram);
|
_pipeline.SetProgram(_edgeProgram);
|
||||||
@ -215,7 +216,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
|||||||
|
|
||||||
ReadOnlySpan<float> resolutionBuffer = stackalloc float[] { view.Width, view.Height };
|
ReadOnlySpan<float> resolutionBuffer = stackalloc float[] { view.Width, view.Height };
|
||||||
int rangeSize = resolutionBuffer.Length * sizeof(float);
|
int rangeSize = resolutionBuffer.Length * sizeof(float);
|
||||||
using var buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize);
|
using ScopedTemporaryBuffer buffer = _renderer.BufferManager.ReserveOrCreate(_renderer, cbs, rangeSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked(buffer.Offset, resolutionBuffer);
|
buffer.Holder.SetDataUnchecked(buffer.Offset, resolutionBuffer);
|
||||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, buffer.Range) });
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(2, buffer.Range) });
|
||||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_device = device;
|
_device = device;
|
||||||
_concurrentWaitUnsupported = concurrentWaitUnsupported;
|
_concurrentWaitUnsupported = concurrentWaitUnsupported;
|
||||||
|
|
||||||
var fenceCreateInfo = new FenceCreateInfo
|
FenceCreateInfo fenceCreateInfo = new FenceCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.FenceCreateInfo,
|
SType = StructureType.FenceCreateInfo,
|
||||||
};
|
};
|
||||||
|
@ -96,11 +96,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public bool BufferFormatSupports(FormatFeatureFlags flags, Format format)
|
public bool BufferFormatSupports(FormatFeatureFlags flags, Format format)
|
||||||
{
|
{
|
||||||
var formatFeatureFlags = _bufferTable[(int)format];
|
FormatFeatureFlags formatFeatureFlags = _bufferTable[(int)format];
|
||||||
|
|
||||||
if (formatFeatureFlags == 0)
|
if (formatFeatureFlags == 0)
|
||||||
{
|
{
|
||||||
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, FormatTable.GetFormat(format), out var fp);
|
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, FormatTable.GetFormat(format), out FormatProperties fp);
|
||||||
formatFeatureFlags = fp.BufferFeatures;
|
formatFeatureFlags = fp.BufferFeatures;
|
||||||
_bufferTable[(int)format] = formatFeatureFlags;
|
_bufferTable[(int)format] = formatFeatureFlags;
|
||||||
}
|
}
|
||||||
@ -129,18 +129,18 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public bool BufferFormatSupports(FormatFeatureFlags flags, VkFormat format)
|
public bool BufferFormatSupports(FormatFeatureFlags flags, VkFormat format)
|
||||||
{
|
{
|
||||||
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, format, out var fp);
|
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, format, out FormatProperties fp);
|
||||||
|
|
||||||
return (fp.BufferFeatures & flags) == flags;
|
return (fp.BufferFeatures & flags) == flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OptimalFormatSupports(FormatFeatureFlags flags, Format format)
|
public bool OptimalFormatSupports(FormatFeatureFlags flags, Format format)
|
||||||
{
|
{
|
||||||
var formatFeatureFlags = _optimalTable[(int)format];
|
FormatFeatureFlags formatFeatureFlags = _optimalTable[(int)format];
|
||||||
|
|
||||||
if (formatFeatureFlags == 0)
|
if (formatFeatureFlags == 0)
|
||||||
{
|
{
|
||||||
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, FormatTable.GetFormat(format), out var fp);
|
_api.GetPhysicalDeviceFormatProperties(_physicalDevice, FormatTable.GetFormat(format), out FormatProperties fp);
|
||||||
formatFeatureFlags = fp.OptimalTilingFeatures;
|
formatFeatureFlags = fp.OptimalTilingFeatures;
|
||||||
_optimalTable[(int)format] = formatFeatureFlags;
|
_optimalTable[(int)format] = formatFeatureFlags;
|
||||||
}
|
}
|
||||||
@ -150,11 +150,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public VkFormat ConvertToVkFormat(Format srcFormat, bool storageFeatureFlagRequired)
|
public VkFormat ConvertToVkFormat(Format srcFormat, bool storageFeatureFlagRequired)
|
||||||
{
|
{
|
||||||
var format = FormatTable.GetFormat(srcFormat);
|
VkFormat format = FormatTable.GetFormat(srcFormat);
|
||||||
|
|
||||||
var requiredFeatures = FormatFeatureFlags.SampledImageBit |
|
FormatFeatureFlags requiredFeatures = FormatFeatureFlags.SampledImageBit |
|
||||||
FormatFeatureFlags.TransferSrcBit |
|
FormatFeatureFlags.TransferSrcBit |
|
||||||
FormatFeatureFlags.TransferDstBit;
|
FormatFeatureFlags.TransferDstBit;
|
||||||
|
|
||||||
if (srcFormat.IsDepthOrStencil())
|
if (srcFormat.IsDepthOrStencil())
|
||||||
{
|
{
|
||||||
@ -192,7 +192,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public VkFormat ConvertToVertexVkFormat(Format srcFormat)
|
public VkFormat ConvertToVertexVkFormat(Format srcFormat)
|
||||||
{
|
{
|
||||||
var format = FormatTable.GetFormat(srcFormat);
|
VkFormat format = FormatTable.GetFormat(srcFormat);
|
||||||
|
|
||||||
if (!BufferFormatSupports(FormatFeatureFlags.VertexBufferBit, srcFormat) ||
|
if (!BufferFormatSupports(FormatFeatureFlags.VertexBufferBit, srcFormat) ||
|
||||||
(IsRGB16IntFloat(srcFormat) && VulkanConfiguration.ForceRGB16IntFloatUnsupported))
|
(IsRGB16IntFloat(srcFormat) && VulkanConfiguration.ForceRGB16IntFloatUnsupported))
|
||||||
|
@ -2,6 +2,7 @@ using Ryujinx.Graphics.GAL;
|
|||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
using VkFormat = Silk.NET.Vulkan.Format;
|
using VkFormat = Silk.NET.Vulkan.Format;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
@ -33,7 +34,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public FramebufferParams(Device device, TextureView view, uint width, uint height)
|
public FramebufferParams(Device device, TextureView view, uint width, uint height)
|
||||||
{
|
{
|
||||||
var format = view.Info.Format;
|
Format format = view.Info.Format;
|
||||||
|
|
||||||
bool isDepthStencil = format.IsDepthOrStencil();
|
bool isDepthStencil = format.IsDepthOrStencil();
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (IsValidTextureView(color))
|
if (IsValidTextureView(color))
|
||||||
{
|
{
|
||||||
var texture = (TextureView)color;
|
TextureView texture = (TextureView)color;
|
||||||
|
|
||||||
_attachments[index] = texture.GetImageViewForAttachment();
|
_attachments[index] = texture.GetImageViewForAttachment();
|
||||||
_colors[index] = texture;
|
_colors[index] = texture;
|
||||||
@ -107,7 +108,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
AttachmentFormats[index] = texture.VkFormat;
|
AttachmentFormats[index] = texture.VkFormat;
|
||||||
AttachmentIndices[index] = bindIndex;
|
AttachmentIndices[index] = bindIndex;
|
||||||
|
|
||||||
var format = texture.Info.Format;
|
Format format = texture.Info.Format;
|
||||||
|
|
||||||
if (format.IsInteger())
|
if (format.IsInteger())
|
||||||
{
|
{
|
||||||
@ -184,7 +185,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (_colors != null && (uint)index < _colors.Length)
|
if (_colors != null && (uint)index < _colors.Length)
|
||||||
{
|
{
|
||||||
var format = _colors[index].Info.Format;
|
Format format = _colors[index].Info.Format;
|
||||||
|
|
||||||
if (format.IsSint())
|
if (format.IsSint())
|
||||||
{
|
{
|
||||||
@ -239,7 +240,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
attachments[i] = _attachments[i].Get(cbs).Value;
|
attachments[i] = _attachments[i].Get(cbs).Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
var framebufferCreateInfo = new FramebufferCreateInfo
|
FramebufferCreateInfo framebufferCreateInfo = new FramebufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.FramebufferCreateInfo,
|
SType = StructureType.FramebufferCreateInfo,
|
||||||
RenderPass = renderPass.Get(cbs).Value,
|
RenderPass = renderPass.Get(cbs).Value,
|
||||||
@ -250,13 +251,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Layers = Layers,
|
Layers = Layers,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CreateFramebuffer(_device, in framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
api.CreateFramebuffer(_device, in framebufferCreateInfo, null, out Framebuffer framebuffer).ThrowOnError();
|
||||||
return new Auto<DisposableFramebuffer>(new DisposableFramebuffer(api, _device, framebuffer), null, _attachments);
|
return new Auto<DisposableFramebuffer>(new DisposableFramebuffer(api, _device, framebuffer), null, _attachments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureView[] GetAttachmentViews()
|
public TextureView[] GetAttachmentViews()
|
||||||
{
|
{
|
||||||
var result = new TextureView[_attachments.Length];
|
TextureView[] result = new TextureView[_attachments.Length];
|
||||||
|
|
||||||
_colors?.CopyTo(result, 0);
|
_colors?.CopyTo(result, 0);
|
||||||
|
|
||||||
@ -277,7 +278,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (_colors != null)
|
if (_colors != null)
|
||||||
{
|
{
|
||||||
foreach (var color in _colors)
|
foreach (TextureView color in _colors)
|
||||||
{
|
{
|
||||||
// If Clear or DontCare were used, this would need to be write bit.
|
// If Clear or DontCare were used, this would need to be write bit.
|
||||||
color.Storage?.QueueLoadOpBarrier(cbs, false);
|
color.Storage?.QueueLoadOpBarrier(cbs, false);
|
||||||
@ -293,7 +294,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (_colors != null)
|
if (_colors != null)
|
||||||
{
|
{
|
||||||
foreach (var color in _colors)
|
foreach (TextureView color in _colors)
|
||||||
{
|
{
|
||||||
color.Storage?.AddStoreOpUsage(false);
|
color.Storage?.AddStoreOpUsage(false);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void Add(ref TKey key, TValue value)
|
public void Add(ref TKey key, TValue value)
|
||||||
{
|
{
|
||||||
var entry = new Entry
|
Entry entry = new Entry
|
||||||
{
|
{
|
||||||
Hash = key.GetHashCode(),
|
Hash = key.GetHashCode(),
|
||||||
Key = key,
|
Key = key,
|
||||||
@ -75,7 +75,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int hashCode = key.GetHashCode();
|
int hashCode = key.GetHashCode();
|
||||||
int bucketIndex = hashCode & TotalBucketsMask;
|
int bucketIndex = hashCode & TotalBucketsMask;
|
||||||
|
|
||||||
ref var bucket = ref _hashTable[bucketIndex];
|
ref Bucket bucket = ref _hashTable[bucketIndex];
|
||||||
if (bucket.Entries != null)
|
if (bucket.Entries != null)
|
||||||
{
|
{
|
||||||
int index = bucket.Length;
|
int index = bucket.Length;
|
||||||
@ -102,11 +102,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
int hashCode = key.GetHashCode();
|
int hashCode = key.GetHashCode();
|
||||||
|
|
||||||
ref var bucket = ref _hashTable[hashCode & TotalBucketsMask];
|
ref Bucket bucket = ref _hashTable[hashCode & TotalBucketsMask];
|
||||||
var entries = bucket.AsSpan();
|
Span<Entry> entries = bucket.AsSpan();
|
||||||
for (int i = 0; i < entries.Length; i++)
|
for (int i = 0; i < entries.Length; i++)
|
||||||
{
|
{
|
||||||
ref var entry = ref entries[i];
|
ref Entry entry = ref entries[i];
|
||||||
|
|
||||||
if (entry.Hash == hashCode && entry.Key.Equals(ref key))
|
if (entry.Hash == hashCode && entry.Key.Equals(ref key))
|
||||||
{
|
{
|
||||||
@ -124,10 +124,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
int hashCode = key.GetHashCode();
|
int hashCode = key.GetHashCode();
|
||||||
|
|
||||||
var entries = _hashTable[hashCode & TotalBucketsMask].AsSpan();
|
Span<Entry> entries = _hashTable[hashCode & TotalBucketsMask].AsSpan();
|
||||||
for (int i = 0; i < entries.Length; i++)
|
for (int i = 0; i < entries.Length; i++)
|
||||||
{
|
{
|
||||||
ref var entry = ref entries[i];
|
ref Entry entry = ref entries[i];
|
||||||
|
|
||||||
if (entry.Hash == hashCode && entry.Key.Equals(ref key))
|
if (entry.Hash == hashCode && entry.Key.Equals(ref key))
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,7 @@ using Silk.NET.Vulkan;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||||
using Format = Ryujinx.Graphics.GAL.Format;
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
||||||
@ -64,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_samplerLinear = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
_samplerLinear = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||||
_samplerNearest = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
_samplerNearest = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
||||||
|
|
||||||
var blitResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout blitResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1)
|
.Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1)
|
||||||
.Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build();
|
.Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build();
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
new ShaderSource(ReadSpirv("ColorBlitClearAlphaFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorBlitClearAlphaFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, blitResourceLayout);
|
}, blitResourceLayout);
|
||||||
|
|
||||||
var colorClearResourceLayout = new ResourceLayoutBuilder().Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1).Build();
|
ResourceLayout colorClearResourceLayout = new ResourceLayoutBuilder().Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1).Build();
|
||||||
|
|
||||||
_programColorClearF = gd.CreateProgramWithMinimalLayout(new[]
|
_programColorClearF = gd.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
@ -112,7 +113,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
new ShaderSource(ReadSpirv("DepthStencilClearFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("DepthStencilClearFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorClearResourceLayout);
|
}, colorClearResourceLayout);
|
||||||
|
|
||||||
var strideChangeResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout strideChangeResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
||||||
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
|
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
|
||||||
@ -122,7 +123,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
new ShaderSource(ReadSpirv("ChangeBufferStride.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ChangeBufferStride.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, strideChangeResourceLayout);
|
}, strideChangeResourceLayout);
|
||||||
|
|
||||||
var colorCopyResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout colorCopyResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 0)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 0)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0, true).Build();
|
||||||
@ -142,7 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
new ShaderSource(ReadSpirv("ColorCopyWideningCompute.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorCopyWideningCompute.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, colorCopyResourceLayout);
|
}, colorCopyResourceLayout);
|
||||||
|
|
||||||
var colorDrawToMsResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout colorDrawToMsResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0)
|
.Add(ResourceStages.Fragment, ResourceType.UniformBuffer, 0)
|
||||||
.Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build();
|
.Add(ResourceStages.Fragment, ResourceType.TextureAndSampler, 0).Build();
|
||||||
|
|
||||||
@ -152,7 +153,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
new ShaderSource(ReadSpirv("ColorDrawToMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ColorDrawToMsFragment.spv"), ShaderStage.Fragment, TargetLanguage.Spirv),
|
||||||
}, colorDrawToMsResourceLayout);
|
}, colorDrawToMsResourceLayout);
|
||||||
|
|
||||||
var convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout convertD32S8ToD24S8ResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
||||||
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
|
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
|
||||||
@ -162,7 +163,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
new ShaderSource(ReadSpirv("ConvertD32S8ToD24S8.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ConvertD32S8ToD24S8.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, convertD32S8ToD24S8ResourceLayout);
|
}, convertD32S8ToD24S8ResourceLayout);
|
||||||
|
|
||||||
var convertIndexBufferResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout convertIndexBufferResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
||||||
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
|
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
|
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true).Build();
|
||||||
@ -172,7 +173,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
new ShaderSource(ReadSpirv("ConvertIndexBuffer.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
new ShaderSource(ReadSpirv("ConvertIndexBuffer.spv"), ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, convertIndexBufferResourceLayout);
|
}, convertIndexBufferResourceLayout);
|
||||||
|
|
||||||
var convertIndirectDataResourceLayout = new ResourceLayoutBuilder()
|
ResourceLayout convertIndirectDataResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
.Add(ResourceStages.Compute, ResourceType.UniformBuffer, 0)
|
||||||
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
|
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true)
|
.Add(ResourceStages.Compute, ResourceType.StorageBuffer, 2, true)
|
||||||
@ -254,17 +255,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
gd.FlushAllCommands();
|
gd.FlushAllCommands();
|
||||||
|
|
||||||
using var cbs = gd.CommandBufferPool.Rent();
|
using CommandBufferScoped cbs = gd.CommandBufferPool.Rent();
|
||||||
|
|
||||||
for (int l = 0; l < levels; l++)
|
for (int l = 0; l < levels; l++)
|
||||||
{
|
{
|
||||||
var mipSrcRegion = new Extents2D(
|
Extents2D mipSrcRegion = new Extents2D(
|
||||||
srcRegion.X1 >> l,
|
srcRegion.X1 >> l,
|
||||||
srcRegion.Y1 >> l,
|
srcRegion.Y1 >> l,
|
||||||
srcRegion.X2 >> l,
|
srcRegion.X2 >> l,
|
||||||
srcRegion.Y2 >> l);
|
srcRegion.Y2 >> l);
|
||||||
|
|
||||||
var mipDstRegion = new Extents2D(
|
Extents2D mipDstRegion = new Extents2D(
|
||||||
dstRegion.X1 >> l,
|
dstRegion.X1 >> l,
|
||||||
dstRegion.Y1 >> l,
|
dstRegion.Y1 >> l,
|
||||||
dstRegion.X2 >> l,
|
dstRegion.X2 >> l,
|
||||||
@ -272,8 +273,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int z = 0; z < layers; z++)
|
for (int z = 0; z < layers; z++)
|
||||||
{
|
{
|
||||||
var srcView = Create2DLayerView(src, z, l);
|
TextureView srcView = Create2DLayerView(src, z, l);
|
||||||
var dstView = Create2DLayerView(dst, z, l);
|
TextureView dstView = Create2DLayerView(dst, z, l);
|
||||||
|
|
||||||
if (isDepthOrStencil)
|
if (isDepthOrStencil)
|
||||||
{
|
{
|
||||||
@ -334,7 +335,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int dstWidth = Math.Max(1, dst.Width >> mipDstLevel);
|
int dstWidth = Math.Max(1, dst.Width >> mipDstLevel);
|
||||||
int dstHeight = Math.Max(1, dst.Height >> mipDstLevel);
|
int dstHeight = Math.Max(1, dst.Height >> mipDstLevel);
|
||||||
|
|
||||||
var extents = new Extents2D(
|
Extents2D extents = new Extents2D(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
Math.Min(srcWidth, dstWidth),
|
Math.Min(srcWidth, dstWidth),
|
||||||
@ -342,8 +343,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
var srcView = Create2DLayerView(src, srcLayer + z, mipSrcLevel);
|
TextureView srcView = Create2DLayerView(src, srcLayer + z, mipSrcLevel);
|
||||||
var dstView = Create2DLayerView(dst, dstLayer + z, mipDstLevel);
|
TextureView dstView = Create2DLayerView(dst, dstLayer + z, mipDstLevel);
|
||||||
|
|
||||||
BlitColor(
|
BlitColor(
|
||||||
gd,
|
gd,
|
||||||
@ -381,7 +382,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
const int RegionBufferSize = 16;
|
const int RegionBufferSize = 16;
|
||||||
|
|
||||||
var sampler = linearFilter ? _samplerLinear : _samplerNearest;
|
ISampler sampler = linearFilter ? _samplerLinear : _samplerNearest;
|
||||||
|
|
||||||
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, src, sampler);
|
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, src, sampler);
|
||||||
|
|
||||||
@ -402,7 +403,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
(region[2], region[3]) = (region[3], region[2]);
|
(region[2], region[3]) = (region[3], region[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, RegionBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, RegionBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked<float>(buffer.Offset, region);
|
buffer.Holder.SetDataUnchecked<float>(buffer.Offset, region);
|
||||||
|
|
||||||
@ -410,7 +411,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(
|
Rectangle<float> rect = new Rectangle<float>(
|
||||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||||
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
||||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||||
@ -498,7 +499,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
(region[2], region[3]) = (region[3], region[2]);
|
(region[2], region[3]) = (region[3], region[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, RegionBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, RegionBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked<float>(buffer.Offset, region);
|
buffer.Holder.SetDataUnchecked<float>(buffer.Offset, region);
|
||||||
|
|
||||||
@ -506,7 +507,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(
|
Rectangle<float> rect = new Rectangle<float>(
|
||||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||||
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
||||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||||
@ -529,11 +530,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_pipeline.SetViewports(viewports);
|
_pipeline.SetViewports(viewports);
|
||||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
ImageAspectFlags aspectFlags = src.Info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
if (aspectFlags.HasFlag(ImageAspectFlags.DepthBit))
|
if (aspectFlags.HasFlag(ImageAspectFlags.DepthBit))
|
||||||
{
|
{
|
||||||
var depthTexture = CreateDepthOrStencilView(src, DepthStencilMode.Depth);
|
TextureView depthTexture = CreateDepthOrStencilView(src, DepthStencilMode.Depth);
|
||||||
|
|
||||||
BlitDepthStencilDraw(depthTexture, isDepth: true);
|
BlitDepthStencilDraw(depthTexture, isDepth: true);
|
||||||
|
|
||||||
@ -545,7 +546,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (aspectFlags.HasFlag(ImageAspectFlags.StencilBit) && _programStencilBlit != null)
|
if (aspectFlags.HasFlag(ImageAspectFlags.StencilBit) && _programStencilBlit != null)
|
||||||
{
|
{
|
||||||
var stencilTexture = CreateDepthOrStencilView(src, DepthStencilMode.Stencil);
|
TextureView stencilTexture = CreateDepthOrStencilView(src, DepthStencilMode.Stencil);
|
||||||
|
|
||||||
BlitDepthStencilDraw(stencilTexture, isDepth: false);
|
BlitDepthStencilDraw(stencilTexture, isDepth: false);
|
||||||
|
|
||||||
@ -648,11 +649,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
gd.FlushAllCommands();
|
gd.FlushAllCommands();
|
||||||
|
|
||||||
using var cbs = gd.CommandBufferPool.Rent();
|
using CommandBufferScoped cbs = gd.CommandBufferPool.Rent();
|
||||||
|
|
||||||
_pipeline.SetCommandBuffer(cbs);
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ClearColorBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ClearColorBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked(buffer.Offset, clearColor);
|
buffer.Holder.SetDataUnchecked(buffer.Offset, clearColor);
|
||||||
|
|
||||||
@ -710,11 +711,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
gd.FlushAllCommands();
|
gd.FlushAllCommands();
|
||||||
|
|
||||||
using var cbs = gd.CommandBufferPool.Rent();
|
using CommandBufferScoped cbs = gd.CommandBufferPool.Rent();
|
||||||
|
|
||||||
_pipeline.SetCommandBuffer(cbs);
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ClearColorBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ClearColorBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked<float>(buffer.Offset, stackalloc float[] { depthValue });
|
buffer.Holder.SetDataUnchecked<float>(buffer.Offset, stackalloc float[] { depthValue });
|
||||||
|
|
||||||
@ -771,7 +772,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
(region[2], region[3]) = (region[3], region[2]);
|
(region[2], region[3]) = (region[3], region[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferHandle = gd.BufferManager.CreateWithHandle(gd, RegionBufferSize);
|
BufferHandle bufferHandle = gd.BufferManager.CreateWithHandle(gd, RegionBufferSize);
|
||||||
|
|
||||||
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
|
||||||
|
|
||||||
@ -779,7 +780,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(
|
Rectangle<float> rect = new Rectangle<float>(
|
||||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||||
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
MathF.Min(dstRegion.Y1, dstRegion.Y2),
|
||||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||||
@ -814,14 +815,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int elems = size / stride;
|
int elems = size / stride;
|
||||||
int newSize = elems * newStride;
|
int newSize = elems * newStride;
|
||||||
|
|
||||||
var srcBufferAuto = src.GetBuffer();
|
Auto<DisposableBuffer> srcBufferAuto = src.GetBuffer();
|
||||||
var dstBufferAuto = dst.GetBuffer();
|
Auto<DisposableBuffer> dstBufferAuto = dst.GetBuffer();
|
||||||
|
|
||||||
var srcBuffer = srcBufferAuto.Get(cbs, srcOffset, size).Value;
|
Buffer srcBuffer = srcBufferAuto.Get(cbs, srcOffset, size).Value;
|
||||||
var dstBuffer = dstBufferAuto.Get(cbs, 0, newSize).Value;
|
Buffer dstBuffer = dstBufferAuto.Get(cbs, 0, newSize).Value;
|
||||||
|
|
||||||
var access = supportsUint8 ? AccessFlags.ShaderWriteBit : AccessFlags.TransferWriteBit;
|
AccessFlags access = supportsUint8 ? AccessFlags.ShaderWriteBit : AccessFlags.TransferWriteBit;
|
||||||
var stage = supportsUint8 ? PipelineStageFlags.ComputeShaderBit : PipelineStageFlags.TransferBit;
|
PipelineStageFlags stage = supportsUint8 ? PipelineStageFlags.ComputeShaderBit : PipelineStageFlags.TransferBit;
|
||||||
|
|
||||||
BufferHolder.InsertBufferBarrier(
|
BufferHolder.InsertBufferBarrier(
|
||||||
gd,
|
gd,
|
||||||
@ -845,7 +846,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
shaderParams[2] = size;
|
shaderParams[2] = size;
|
||||||
shaderParams[3] = srcOffset;
|
shaderParams[3] = srcOffset;
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
||||||
|
|
||||||
@ -869,7 +870,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
gd.Api.CmdFillBuffer(cbs.CommandBuffer, dstBuffer, 0, Vk.WholeSize, 0);
|
gd.Api.CmdFillBuffer(cbs.CommandBuffer, dstBuffer, 0, Vk.WholeSize, 0);
|
||||||
|
|
||||||
var bufferCopy = new BufferCopy[elems];
|
BufferCopy[] bufferCopy = new BufferCopy[elems];
|
||||||
|
|
||||||
for (ulong i = 0; i < (ulong)elems; i++)
|
for (ulong i = 0; i < (ulong)elems; i++)
|
||||||
{
|
{
|
||||||
@ -909,19 +910,19 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int convertedCount = pattern.GetConvertedCount(indexCount);
|
int convertedCount = pattern.GetConvertedCount(indexCount);
|
||||||
int outputIndexSize = 4;
|
int outputIndexSize = 4;
|
||||||
|
|
||||||
var srcBuffer = src.GetBuffer().Get(cbs, srcOffset, indexCount * indexSize).Value;
|
Buffer srcBuffer = src.GetBuffer().Get(cbs, srcOffset, indexCount * indexSize).Value;
|
||||||
var dstBuffer = dst.GetBuffer().Get(cbs, 0, convertedCount * outputIndexSize).Value;
|
Buffer dstBuffer = dst.GetBuffer().Get(cbs, 0, convertedCount * outputIndexSize).Value;
|
||||||
|
|
||||||
gd.Api.CmdFillBuffer(cbs.CommandBuffer, dstBuffer, 0, Vk.WholeSize, 0);
|
gd.Api.CmdFillBuffer(cbs.CommandBuffer, dstBuffer, 0, Vk.WholeSize, 0);
|
||||||
|
|
||||||
var bufferCopy = new List<BufferCopy>();
|
List<BufferCopy> bufferCopy = new List<BufferCopy>();
|
||||||
int outputOffset = 0;
|
int outputOffset = 0;
|
||||||
|
|
||||||
// Try to merge copies of adjacent indices to reduce copy count.
|
// Try to merge copies of adjacent indices to reduce copy count.
|
||||||
int sequenceStart = 0;
|
int sequenceStart = 0;
|
||||||
int sequenceLength = 0;
|
int sequenceLength = 0;
|
||||||
|
|
||||||
foreach (var index in pattern.GetIndexMapping(indexCount))
|
foreach (int index in pattern.GetIndexMapping(indexCount))
|
||||||
{
|
{
|
||||||
if (sequenceLength > 0)
|
if (sequenceLength > 0)
|
||||||
{
|
{
|
||||||
@ -946,7 +947,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
bufferCopy.Add(new BufferCopy((ulong)(srcOffset + sequenceStart * indexSize), (ulong)outputOffset, (ulong)(indexSize * sequenceLength)));
|
bufferCopy.Add(new BufferCopy((ulong)(srcOffset + sequenceStart * indexSize), (ulong)outputOffset, (ulong)(indexSize * sequenceLength)));
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferCopyArray = bufferCopy.ToArray();
|
BufferCopy[] bufferCopyArray = bufferCopy.ToArray();
|
||||||
|
|
||||||
BufferHolder.InsertBufferBarrier(
|
BufferHolder.InsertBufferBarrier(
|
||||||
gd,
|
gd,
|
||||||
@ -999,7 +1000,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
shaderParams[0] = BitOperations.Log2((uint)ratio);
|
shaderParams[0] = BitOperations.Log2((uint)ratio);
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
||||||
|
|
||||||
@ -1026,8 +1027,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// - Maximum component size is 4 (R32).
|
// - Maximum component size is 4 (R32).
|
||||||
int componentSize = Math.Min(Math.Min(srcBpp, dstBpp), 4);
|
int componentSize = Math.Min(Math.Min(srcBpp, dstBpp), 4);
|
||||||
|
|
||||||
var srcFormat = GetFormat(componentSize, srcBpp / componentSize);
|
Format srcFormat = GetFormat(componentSize, srcBpp / componentSize);
|
||||||
var dstFormat = GetFormat(componentSize, dstBpp / componentSize);
|
Format dstFormat = GetFormat(componentSize, dstBpp / componentSize);
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, buffer.Range) });
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, buffer.Range) });
|
||||||
|
|
||||||
@ -1035,8 +1036,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
var srcView = Create2DLayerView(src, srcLayer + z, srcLevel + l, srcFormat);
|
TextureView srcView = Create2DLayerView(src, srcLayer + z, srcLevel + l, srcFormat);
|
||||||
var dstView = Create2DLayerView(dst, dstLayer + z, dstLevel + l);
|
TextureView dstView = Create2DLayerView(dst, dstLayer + z, dstLevel + l);
|
||||||
|
|
||||||
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Compute, 0, srcView, null);
|
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Compute, 0, srcView, null);
|
||||||
_pipeline.SetImage(ShaderStage.Compute, 0, dstView.GetView(dstFormat));
|
_pipeline.SetImage(ShaderStage.Compute, 0, dstView.GetView(dstFormat));
|
||||||
@ -1083,7 +1084,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
int samples = src.Info.Samples;
|
int samples = src.Info.Samples;
|
||||||
bool isDepthOrStencil = src.Info.Format.IsDepthOrStencil();
|
bool isDepthOrStencil = src.Info.Format.IsDepthOrStencil();
|
||||||
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
ImageAspectFlags aspectFlags = src.Info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
// X and Y are the expected texture samples.
|
// X and Y are the expected texture samples.
|
||||||
// Z and W are the actual texture samples used.
|
// Z and W are the actual texture samples used.
|
||||||
@ -1091,7 +1092,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
(shaderParams[0], shaderParams[1]) = GetSampleCountXYLog2(samples);
|
(shaderParams[0], shaderParams[1]) = GetSampleCountXYLog2(samples);
|
||||||
(shaderParams[2], shaderParams[3]) = GetSampleCountXYLog2((int)TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)samples));
|
(shaderParams[2], shaderParams[3]) = GetSampleCountXYLog2((int)TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)samples));
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
||||||
|
|
||||||
@ -1118,7 +1119,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
Rectangle<float> rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
||||||
|
|
||||||
viewports[0] = new Viewport(
|
viewports[0] = new Viewport(
|
||||||
rect,
|
rect,
|
||||||
@ -1135,8 +1136,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
var srcView = Create2DLayerView(src, srcLayer + z, 0);
|
TextureView srcView = Create2DLayerView(src, srcLayer + z, 0);
|
||||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
TextureView dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||||
|
|
||||||
_pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height);
|
_pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height);
|
||||||
|
|
||||||
@ -1155,7 +1156,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var format = GetFormat(src.Info.BytesPerPixel);
|
Format format = GetFormat(src.Info.BytesPerPixel);
|
||||||
|
|
||||||
int dispatchX = (dst.Info.Width + 31) / 32;
|
int dispatchX = (dst.Info.Width + 31) / 32;
|
||||||
int dispatchY = (dst.Info.Height + 31) / 32;
|
int dispatchY = (dst.Info.Height + 31) / 32;
|
||||||
@ -1164,8 +1165,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
var srcView = Create2DLayerView(src, srcLayer + z, 0, format);
|
TextureView srcView = Create2DLayerView(src, srcLayer + z, 0, format);
|
||||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
TextureView dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||||
|
|
||||||
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Compute, 0, srcView, null);
|
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Compute, 0, srcView, null);
|
||||||
_pipeline.SetImage(ShaderStage.Compute, 0, dstView.GetView(format));
|
_pipeline.SetImage(ShaderStage.Compute, 0, dstView.GetView(format));
|
||||||
@ -1209,7 +1210,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
int samples = dst.Info.Samples;
|
int samples = dst.Info.Samples;
|
||||||
bool isDepthOrStencil = src.Info.Format.IsDepthOrStencil();
|
bool isDepthOrStencil = src.Info.Format.IsDepthOrStencil();
|
||||||
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
ImageAspectFlags aspectFlags = src.Info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
// X and Y are the expected texture samples.
|
// X and Y are the expected texture samples.
|
||||||
// Z and W are the actual texture samples used.
|
// Z and W are the actual texture samples used.
|
||||||
@ -1217,7 +1218,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
(shaderParams[0], shaderParams[1]) = GetSampleCountXYLog2(samples);
|
(shaderParams[0], shaderParams[1]) = GetSampleCountXYLog2(samples);
|
||||||
(shaderParams[2], shaderParams[3]) = GetSampleCountXYLog2((int)TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)samples));
|
(shaderParams[2], shaderParams[3]) = GetSampleCountXYLog2((int)TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)samples));
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
||||||
|
|
||||||
@ -1239,7 +1240,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
Rectangle<float> rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
||||||
|
|
||||||
viewports[0] = new Viewport(
|
viewports[0] = new Viewport(
|
||||||
rect,
|
rect,
|
||||||
@ -1261,8 +1262,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
var srcView = Create2DLayerView(src, srcLayer + z, 0);
|
TextureView srcView = Create2DLayerView(src, srcLayer + z, 0);
|
||||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
TextureView dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||||
|
|
||||||
_pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height);
|
_pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height);
|
||||||
|
|
||||||
@ -1283,13 +1284,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
_pipeline.SetProgram(_programColorDrawToMs);
|
_pipeline.SetProgram(_programColorDrawToMs);
|
||||||
|
|
||||||
var format = GetFormat(src.Info.BytesPerPixel);
|
Format format = GetFormat(src.Info.BytesPerPixel);
|
||||||
var vkFormat = FormatTable.GetFormat(format);
|
VkFormat vkFormat = FormatTable.GetFormat(format);
|
||||||
|
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
var srcView = Create2DLayerView(src, srcLayer + z, 0, format);
|
TextureView srcView = Create2DLayerView(src, srcLayer + z, 0, format);
|
||||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
TextureView dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||||
|
|
||||||
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, srcView, null);
|
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, srcView, null);
|
||||||
_pipeline.SetRenderTarget(dstView.GetView(format), (uint)dst.Width, (uint)dst.Height);
|
_pipeline.SetRenderTarget(dstView.GetView(format), (uint)dst.Width, (uint)dst.Height);
|
||||||
@ -1329,7 +1330,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (aspectFlags.HasFlag(ImageAspectFlags.DepthBit))
|
if (aspectFlags.HasFlag(ImageAspectFlags.DepthBit))
|
||||||
{
|
{
|
||||||
var depthTexture = CreateDepthOrStencilView(src, DepthStencilMode.Depth);
|
TextureView depthTexture = CreateDepthOrStencilView(src, DepthStencilMode.Depth);
|
||||||
|
|
||||||
CopyMSAspectDraw(depthTexture, fromMS, isDepth: true);
|
CopyMSAspectDraw(depthTexture, fromMS, isDepth: true);
|
||||||
|
|
||||||
@ -1341,7 +1342,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (aspectFlags.HasFlag(ImageAspectFlags.StencilBit) && _programStencilDrawToMs != null)
|
if (aspectFlags.HasFlag(ImageAspectFlags.StencilBit) && _programStencilDrawToMs != null)
|
||||||
{
|
{
|
||||||
var stencilTexture = CreateDepthOrStencilView(src, DepthStencilMode.Stencil);
|
TextureView stencilTexture = CreateDepthOrStencilView(src, DepthStencilMode.Stencil);
|
||||||
|
|
||||||
CopyMSAspectDraw(stencilTexture, fromMS, isDepth: false);
|
CopyMSAspectDraw(stencilTexture, fromMS, isDepth: false);
|
||||||
|
|
||||||
@ -1421,14 +1422,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
|
|
||||||
var target = from.Info.Target switch
|
Target target = from.Info.Target switch
|
||||||
{
|
{
|
||||||
Target.Texture1DArray => Target.Texture1D,
|
Target.Texture1DArray => Target.Texture1D,
|
||||||
Target.Texture2DMultisampleArray => Target.Texture2DMultisample,
|
Target.Texture2DMultisampleArray => Target.Texture2DMultisample,
|
||||||
_ => Target.Texture2D,
|
_ => Target.Texture2D,
|
||||||
};
|
};
|
||||||
|
|
||||||
var info = new TextureCreateInfo(
|
TextureCreateInfo info = new TextureCreateInfo(
|
||||||
Math.Max(1, from.Info.Width >> level),
|
Math.Max(1, from.Info.Width >> level),
|
||||||
Math.Max(1, from.Info.Height >> level),
|
Math.Max(1, from.Info.Height >> level),
|
||||||
1,
|
1,
|
||||||
@ -1530,8 +1531,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int convertedCount = pattern.GetConvertedCount(indexCount);
|
int convertedCount = pattern.GetConvertedCount(indexCount);
|
||||||
int outputIndexSize = 4;
|
int outputIndexSize = 4;
|
||||||
|
|
||||||
var srcBuffer = srcIndexBuffer.GetBuffer().Get(cbs, srcIndexBufferOffset, indexCount * indexSize).Value;
|
Buffer srcBuffer = srcIndexBuffer.GetBuffer().Get(cbs, srcIndexBufferOffset, indexCount * indexSize).Value;
|
||||||
var dstBuffer = dstIndexBuffer.GetBuffer().Get(cbs, 0, convertedCount * outputIndexSize).Value;
|
Buffer dstBuffer = dstIndexBuffer.GetBuffer().Get(cbs, 0, convertedCount * outputIndexSize).Value;
|
||||||
|
|
||||||
const int ParamsBufferSize = 24 * sizeof(int);
|
const int ParamsBufferSize = 24 * sizeof(int);
|
||||||
const int ParamsIndirectDispatchOffset = 16 * sizeof(int);
|
const int ParamsIndirectDispatchOffset = 16 * sizeof(int);
|
||||||
@ -1558,9 +1559,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]);
|
pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]);
|
||||||
|
|
||||||
using var patternScoped = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
using ScopedTemporaryBuffer patternScoped = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
||||||
var patternBuffer = patternScoped.Holder;
|
BufferHolder patternBuffer = patternScoped.Holder;
|
||||||
var patternBufferAuto = patternBuffer.GetBuffer();
|
Auto<DisposableBuffer> patternBufferAuto = patternBuffer.GetBuffer();
|
||||||
|
|
||||||
patternBuffer.SetDataUnchecked<int>(patternScoped.Offset, shaderParams);
|
patternBuffer.SetDataUnchecked<int>(patternScoped.Offset, shaderParams);
|
||||||
|
|
||||||
@ -1631,13 +1632,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int inSize = pixelCount * 2 * sizeof(int);
|
int inSize = pixelCount * 2 * sizeof(int);
|
||||||
int outSize = pixelCount * sizeof(int);
|
int outSize = pixelCount * sizeof(int);
|
||||||
|
|
||||||
var srcBufferAuto = src.GetBuffer();
|
Auto<DisposableBuffer> srcBufferAuto = src.GetBuffer();
|
||||||
|
|
||||||
var srcBuffer = srcBufferAuto.Get(cbs, 0, inSize).Value;
|
Buffer srcBuffer = srcBufferAuto.Get(cbs, 0, inSize).Value;
|
||||||
var dstBuffer = dstBufferAuto.Get(cbs, dstOffset, outSize).Value;
|
Buffer dstBuffer = dstBufferAuto.Get(cbs, dstOffset, outSize).Value;
|
||||||
|
|
||||||
var access = AccessFlags.ShaderWriteBit;
|
AccessFlags access = AccessFlags.ShaderWriteBit;
|
||||||
var stage = PipelineStageFlags.ComputeShaderBit;
|
PipelineStageFlags stage = PipelineStageFlags.ComputeShaderBit;
|
||||||
|
|
||||||
BufferHolder.InsertBufferBarrier(
|
BufferHolder.InsertBufferBarrier(
|
||||||
gd,
|
gd,
|
||||||
@ -1668,7 +1669,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
shaderParams[0] = pixelCount;
|
shaderParams[0] = pixelCount;
|
||||||
shaderParams[1] = dstOffset;
|
shaderParams[1] = dstOffset;
|
||||||
|
|
||||||
using var buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
using ScopedTemporaryBuffer buffer = gd.BufferManager.ReserveOrCreate(gd, cbs, ParamsBufferSize);
|
||||||
|
|
||||||
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
buffer.Holder.SetDataUnchecked<int>(buffer.Offset, shaderParams);
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
// Does a compatible allocation exist in the tree?
|
// Does a compatible allocation exist in the tree?
|
||||||
var allocations = new HostMemoryAllocation[10];
|
HostMemoryAllocation[] allocations = new HostMemoryAllocation[10];
|
||||||
|
|
||||||
ulong start = (ulong)pointer;
|
ulong start = (ulong)pointer;
|
||||||
ulong end = start + size;
|
ulong end = start + size;
|
||||||
@ -108,7 +108,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PHostPointer = (void*)pageAlignedPointer,
|
PHostPointer = (void*)pageAlignedPointer,
|
||||||
};
|
};
|
||||||
|
|
||||||
var memoryAllocateInfo = new MemoryAllocateInfo
|
MemoryAllocateInfo memoryAllocateInfo = new MemoryAllocateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryAllocateInfo,
|
SType = StructureType.MemoryAllocateInfo,
|
||||||
AllocationSize = pageAlignedSize,
|
AllocationSize = pageAlignedSize,
|
||||||
@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PNext = &importInfo,
|
PNext = &importInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
Result result = _api.AllocateMemory(_device, in memoryAllocateInfo, null, out var deviceMemory);
|
Result result = _api.AllocateMemory(_device, in memoryAllocateInfo, null, out DeviceMemory deviceMemory);
|
||||||
|
|
||||||
if (result < Result.Success)
|
if (result < Result.Success)
|
||||||
{
|
{
|
||||||
@ -124,9 +124,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var allocation = new MemoryAllocation(this, deviceMemory, pageAlignedPointer, 0, pageAlignedSize);
|
MemoryAllocation allocation = new MemoryAllocation(this, deviceMemory, pageAlignedPointer, 0, pageAlignedSize);
|
||||||
var allocAuto = new Auto<MemoryAllocation>(allocation);
|
Auto<MemoryAllocation> allocAuto = new Auto<MemoryAllocation>(allocation);
|
||||||
var hostAlloc = new HostMemoryAllocation(allocAuto, pageAlignedPointer, pageAlignedSize);
|
HostMemoryAllocation hostAlloc = new HostMemoryAllocation(allocAuto, pageAlignedPointer, pageAlignedSize);
|
||||||
|
|
||||||
allocAuto.IncrementReferenceCount();
|
allocAuto.IncrementReferenceCount();
|
||||||
allocAuto.Dispose(); // Kept alive by ref count only.
|
allocAuto.Dispose(); // Kept alive by ref count only.
|
||||||
@ -145,7 +145,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
// Does a compatible allocation exist in the tree?
|
// Does a compatible allocation exist in the tree?
|
||||||
var allocations = new HostMemoryAllocation[10];
|
HostMemoryAllocation[] allocations = new HostMemoryAllocation[10];
|
||||||
|
|
||||||
ulong start = (ulong)pointer;
|
ulong start = (ulong)pointer;
|
||||||
ulong end = start + size;
|
ulong end = start + size;
|
||||||
|
@ -128,8 +128,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < textures.Length; i++)
|
for (int i = 0; i < textures.Length; i++)
|
||||||
{
|
{
|
||||||
ref var texture = ref textures[i];
|
ref DescriptorImageInfo texture = ref textures[i];
|
||||||
ref var refs = ref _textureRefs[i];
|
ref TextureRef refs = ref _textureRefs[i];
|
||||||
|
|
||||||
if (i > 0 && _textureRefs[i - 1].View == refs.View)
|
if (i > 0 && _textureRefs[i - 1].View == refs.View)
|
||||||
{
|
{
|
||||||
|
@ -115,7 +115,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// Convert the index buffer using the given pattern.
|
// Convert the index buffer using the given pattern.
|
||||||
int indexSize = GetIndexSize();
|
int indexSize = GetIndexSize();
|
||||||
|
|
||||||
(var indexBufferAuto, var indirectBufferAuto) = gd.BufferManager.GetBufferTopologyConversionIndirect(
|
(Auto<DisposableBuffer> indexBufferAuto, Auto<DisposableBuffer> indirectBufferAuto) = gd.BufferManager.GetBufferTopologyConversionIndirect(
|
||||||
gd,
|
gd,
|
||||||
cbs,
|
cbs,
|
||||||
new BufferRange(_handle, _offset, _size),
|
new BufferRange(_handle, _offset, _size),
|
||||||
|
@ -49,7 +49,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _blockLists.Count; i++)
|
for (int i = 0; i < _blockLists.Count; i++)
|
||||||
{
|
{
|
||||||
var bl = _blockLists[i];
|
MemoryAllocatorBlockList bl = _blockLists[i];
|
||||||
if (bl.MemoryTypeIndex == memoryTypeIndex && bl.ForBuffer == isBuffer)
|
if (bl.MemoryTypeIndex == memoryTypeIndex && bl.ForBuffer == isBuffer)
|
||||||
{
|
{
|
||||||
return bl.Allocate(size, alignment, map);
|
return bl.Allocate(size, alignment, map);
|
||||||
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var newBl = new MemoryAllocatorBlockList(_api, _device, memoryTypeIndex, _blockAlignment, isBuffer);
|
MemoryAllocatorBlockList newBl = new MemoryAllocatorBlockList(_api, _device, memoryTypeIndex, _blockAlignment, isBuffer);
|
||||||
_blockLists.Add(newBl);
|
_blockLists.Add(newBl);
|
||||||
|
|
||||||
return newBl.Allocate(size, alignment, map);
|
return newBl.Allocate(size, alignment, map);
|
||||||
@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _physicalDevice.PhysicalDeviceMemoryProperties.MemoryTypeCount; i++)
|
for (int i = 0; i < _physicalDevice.PhysicalDeviceMemoryProperties.MemoryTypeCount; i++)
|
||||||
{
|
{
|
||||||
var type = _physicalDevice.PhysicalDeviceMemoryProperties.MemoryTypes[i];
|
MemoryType type = _physicalDevice.PhysicalDeviceMemoryProperties.MemoryTypes[i];
|
||||||
|
|
||||||
if ((memoryTypeBits & (1 << i)) != 0)
|
if ((memoryTypeBits & (1 << i)) != 0)
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _freeRanges.Count; i++)
|
for (int i = 0; i < _freeRanges.Count; i++)
|
||||||
{
|
{
|
||||||
var range = _freeRanges[i];
|
Range range = _freeRanges[i];
|
||||||
|
|
||||||
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
|
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
|
||||||
ulong sizeDelta = alignedOffset - range.Offset;
|
ulong sizeDelta = alignedOffset - range.Offset;
|
||||||
@ -88,7 +88,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void InsertFreeRange(ulong offset, ulong size)
|
private void InsertFreeRange(ulong offset, ulong size)
|
||||||
{
|
{
|
||||||
var range = new Range(offset, size);
|
Range range = new Range(offset, size);
|
||||||
int index = _freeRanges.BinarySearch(range);
|
int index = _freeRanges.BinarySearch(range);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
@ -101,7 +101,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private void InsertFreeRangeComingled(ulong offset, ulong size)
|
private void InsertFreeRangeComingled(ulong offset, ulong size)
|
||||||
{
|
{
|
||||||
ulong endOffset = offset + size;
|
ulong endOffset = offset + size;
|
||||||
var range = new Range(offset, size);
|
Range range = new Range(offset, size);
|
||||||
int index = _freeRanges.BinarySearch(range);
|
int index = _freeRanges.BinarySearch(range);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
@ -194,7 +194,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < _blocks.Count; i++)
|
for (int i = 0; i < _blocks.Count; i++)
|
||||||
{
|
{
|
||||||
var block = _blocks[i];
|
Block block = _blocks[i];
|
||||||
|
|
||||||
if (block.Mapped == map && block.Size >= size)
|
if (block.Mapped == map && block.Size >= size)
|
||||||
{
|
{
|
||||||
@ -213,14 +213,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
ulong blockAlignedSize = BitUtils.AlignUp(size, (ulong)_blockAlignment);
|
ulong blockAlignedSize = BitUtils.AlignUp(size, (ulong)_blockAlignment);
|
||||||
|
|
||||||
var memoryAllocateInfo = new MemoryAllocateInfo
|
MemoryAllocateInfo memoryAllocateInfo = new MemoryAllocateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryAllocateInfo,
|
SType = StructureType.MemoryAllocateInfo,
|
||||||
AllocationSize = blockAlignedSize,
|
AllocationSize = blockAlignedSize,
|
||||||
MemoryTypeIndex = (uint)MemoryTypeIndex,
|
MemoryTypeIndex = (uint)MemoryTypeIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
_api.AllocateMemory(_device, in memoryAllocateInfo, null, out var deviceMemory).ThrowOnError();
|
_api.AllocateMemory(_device, in memoryAllocateInfo, null, out DeviceMemory deviceMemory).ThrowOnError();
|
||||||
|
|
||||||
nint hostPointer = nint.Zero;
|
nint hostPointer = nint.Zero;
|
||||||
|
|
||||||
@ -231,7 +231,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
hostPointer = (nint)pointer;
|
hostPointer = (nint)pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newBlock = new Block(deviceMemory, hostPointer, blockAlignedSize);
|
Block newBlock = new Block(deviceMemory, hostPointer, blockAlignedSize);
|
||||||
|
|
||||||
InsertBlock(newBlock);
|
InsertBlock(newBlock);
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
|||||||
|
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
var configSize = (nint)Marshal.SizeOf<MVKConfiguration>();
|
IntPtr configSize = (nint)Marshal.SizeOf<MVKConfiguration>();
|
||||||
|
|
||||||
vkGetMoltenVKConfigurationMVK(nint.Zero, out MVKConfiguration config, configSize);
|
vkGetMoltenVKConfigurationMVK(nint.Zero, out MVKConfiguration config, configSize);
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < _fences.Length; i++)
|
for (int i = 0; i < _fences.Length; i++)
|
||||||
{
|
{
|
||||||
var fence = _fences[i];
|
FenceHolder fence = _fences[i];
|
||||||
|
|
||||||
if (fence != null)
|
if (fence != null)
|
||||||
{
|
{
|
||||||
@ -253,7 +253,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < _fences.Length; i++)
|
for (int i = 0; i < _fences.Length; i++)
|
||||||
{
|
{
|
||||||
var fence = _fences[i];
|
FenceHolder fence = _fences[i];
|
||||||
|
|
||||||
if (fence != null && _bufferUsageBitmap.OverlapsWith(i, offset, size))
|
if (fence != null && _bufferUsageBitmap.OverlapsWith(i, offset, size))
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
@ -16,7 +18,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private BufferHolder ResizeIfNeeded(int size)
|
private BufferHolder ResizeIfNeeded(int size)
|
||||||
{
|
{
|
||||||
var flushStorage = _flushStorage;
|
BufferHolder flushStorage = _flushStorage;
|
||||||
|
|
||||||
if (flushStorage == null || size > _flushStorage.Size)
|
if (flushStorage == null || size > _flushStorage.Size)
|
||||||
{
|
{
|
||||||
@ -31,13 +33,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Span<byte> GetBufferData(CommandBufferPool cbp, BufferHolder buffer, int offset, int size)
|
public Span<byte> GetBufferData(CommandBufferPool cbp, BufferHolder buffer, int offset, int size)
|
||||||
{
|
{
|
||||||
var flushStorage = ResizeIfNeeded(size);
|
BufferHolder flushStorage = ResizeIfNeeded(size);
|
||||||
Auto<DisposableBuffer> srcBuffer;
|
Auto<DisposableBuffer> srcBuffer;
|
||||||
|
|
||||||
using (var cbs = cbp.Rent())
|
using (CommandBufferScoped cbs = cbp.Rent())
|
||||||
{
|
{
|
||||||
srcBuffer = buffer.GetBuffer(cbs.CommandBuffer);
|
srcBuffer = buffer.GetBuffer(cbs.CommandBuffer);
|
||||||
var dstBuffer = flushStorage.GetBuffer(cbs.CommandBuffer);
|
Auto<DisposableBuffer> dstBuffer = flushStorage.GetBuffer(cbs.CommandBuffer);
|
||||||
|
|
||||||
if (srcBuffer.TryIncrementReferenceCount())
|
if (srcBuffer.TryIncrementReferenceCount())
|
||||||
{
|
{
|
||||||
@ -59,12 +61,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
TextureCreateInfo info = view.Info;
|
TextureCreateInfo info = view.Info;
|
||||||
|
|
||||||
var flushStorage = ResizeIfNeeded(size);
|
BufferHolder flushStorage = ResizeIfNeeded(size);
|
||||||
|
|
||||||
using (var cbs = cbp.Rent())
|
using (CommandBufferScoped cbs = cbp.Rent())
|
||||||
{
|
{
|
||||||
var buffer = flushStorage.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
Buffer buffer = flushStorage.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
||||||
var image = view.GetImage().Get(cbs).Value;
|
Image image = view.GetImage().Get(cbs).Value;
|
||||||
|
|
||||||
view.CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, 0, 0, info.GetLayers(), info.Levels, singleSlice: false);
|
view.CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, 0, 0, info.GetLayers(), info.Levels, singleSlice: false);
|
||||||
}
|
}
|
||||||
@ -75,12 +77,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size, int layer, int level)
|
public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size, int layer, int level)
|
||||||
{
|
{
|
||||||
var flushStorage = ResizeIfNeeded(size);
|
BufferHolder flushStorage = ResizeIfNeeded(size);
|
||||||
|
|
||||||
using (var cbs = cbp.Rent())
|
using (CommandBufferScoped cbs = cbp.Rent())
|
||||||
{
|
{
|
||||||
var buffer = flushStorage.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
Buffer buffer = flushStorage.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
||||||
var image = view.GetImage().Get(cbs).Value;
|
Image image = view.GetImage().Get(cbs).Value;
|
||||||
|
|
||||||
view.CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, layer, level, 1, 1, singleSlice: true);
|
view.CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, layer, level, 1, 1, singleSlice: true);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
@ -7,6 +8,8 @@ using System.Linq;
|
|||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using BlendOp = Silk.NET.Vulkan.BlendOp;
|
||||||
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||||
using Format = Ryujinx.Graphics.GAL.Format;
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
using FrontFace = Ryujinx.Graphics.GAL.FrontFace;
|
using FrontFace = Ryujinx.Graphics.GAL.FrontFace;
|
||||||
@ -102,7 +105,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
AutoFlush = new AutoFlushCounter(gd);
|
AutoFlush = new AutoFlushCounter(gd);
|
||||||
EndRenderPassDelegate = EndRenderPass;
|
EndRenderPassDelegate = EndRenderPass;
|
||||||
|
|
||||||
var pipelineCacheCreateInfo = new PipelineCacheCreateInfo
|
PipelineCacheCreateInfo pipelineCacheCreateInfo = new PipelineCacheCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineCacheCreateInfo,
|
SType = StructureType.PipelineCacheCreateInfo,
|
||||||
};
|
};
|
||||||
@ -117,7 +120,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
const int EmptyVbSize = 16;
|
const int EmptyVbSize = 16;
|
||||||
|
|
||||||
using var emptyVb = gd.BufferManager.Create(gd, EmptyVbSize);
|
using BufferHolder emptyVb = gd.BufferManager.Create(gd, EmptyVbSize);
|
||||||
emptyVb.SetData(0, new byte[EmptyVbSize]);
|
emptyVb.SetData(0, new byte[EmptyVbSize]);
|
||||||
_vertexBuffers[0] = new VertexBufferState(emptyVb.GetBuffer(), 0, 0, EmptyVbSize);
|
_vertexBuffers[0] = new VertexBufferState(emptyVb.GetBuffer(), 0, 0, EmptyVbSize);
|
||||||
_vertexBuffersDirty = ulong.MaxValue >> (64 - _vertexBuffers.Length);
|
_vertexBuffersDirty = ulong.MaxValue >> (64 - _vertexBuffers.Length);
|
||||||
@ -174,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
|
||||||
var dst = Gd.BufferManager.GetBuffer(CommandBuffer, destination, offset, size, true).Get(Cbs, offset, size, true).Value;
|
Buffer dst = Gd.BufferManager.GetBuffer(CommandBuffer, destination, offset, size, true).Get(Cbs, offset, size, true).Value;
|
||||||
|
|
||||||
BufferHolder.InsertBufferBarrier(
|
BufferHolder.InsertBufferBarrier(
|
||||||
Gd,
|
Gd,
|
||||||
@ -217,9 +220,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
BeginRenderPass();
|
BeginRenderPass();
|
||||||
|
|
||||||
var clearValue = new ClearValue(new ClearColorValue(color.Red, color.Green, color.Blue, color.Alpha));
|
ClearValue clearValue = new ClearValue(new ClearColorValue(color.Red, color.Green, color.Blue, color.Alpha));
|
||||||
var attachment = new ClearAttachment(ImageAspectFlags.ColorBit, (uint)index, clearValue);
|
ClearAttachment attachment = new ClearAttachment(ImageAspectFlags.ColorBit, (uint)index, clearValue);
|
||||||
var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
|
ClearRect clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
|
||||||
|
|
||||||
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
||||||
}
|
}
|
||||||
@ -231,8 +234,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var clearValue = new ClearValue(null, new ClearDepthStencilValue(depthValue, (uint)stencilValue));
|
ClearValue clearValue = new ClearValue(null, new ClearDepthStencilValue(depthValue, (uint)stencilValue));
|
||||||
var flags = depthMask ? ImageAspectFlags.DepthBit : 0;
|
ImageAspectFlags flags = depthMask ? ImageAspectFlags.DepthBit : 0;
|
||||||
|
|
||||||
if (stencilMask)
|
if (stencilMask)
|
||||||
{
|
{
|
||||||
@ -255,8 +258,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
BeginRenderPass();
|
BeginRenderPass();
|
||||||
|
|
||||||
var attachment = new ClearAttachment(flags, 0, clearValue);
|
ClearAttachment attachment = new ClearAttachment(flags, 0, clearValue);
|
||||||
var clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
|
ClearRect clearRect = FramebufferParams.GetClearRect(ClearScissor, layer, layerCount);
|
||||||
|
|
||||||
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
|
||||||
}
|
}
|
||||||
@ -270,8 +273,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
|
||||||
var src = Gd.BufferManager.GetBuffer(CommandBuffer, source, srcOffset, size, false);
|
Auto<DisposableBuffer> src = Gd.BufferManager.GetBuffer(CommandBuffer, source, srcOffset, size, false);
|
||||||
var dst = Gd.BufferManager.GetBuffer(CommandBuffer, destination, dstOffset, size, true);
|
Auto<DisposableBuffer> dst = Gd.BufferManager.GetBuffer(CommandBuffer, destination, dstOffset, size, true);
|
||||||
|
|
||||||
BufferHolder.Copy(Gd, Cbs, src, dst, srcOffset, dstOffset, size);
|
BufferHolder.Copy(Gd, Cbs, src, dst, srcOffset, dstOffset, size);
|
||||||
}
|
}
|
||||||
@ -350,7 +353,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
};
|
};
|
||||||
|
|
||||||
BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount);
|
BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount);
|
||||||
var buffer = Gd.BufferManager.GetBuffer(CommandBuffer, handle, false);
|
Auto<DisposableBuffer> buffer = Gd.BufferManager.GetBuffer(CommandBuffer, handle, false);
|
||||||
|
|
||||||
Gd.Api.CmdBindIndexBuffer(CommandBuffer, buffer.Get(Cbs, 0, indexCount * sizeof(int)).Value, 0, Silk.NET.Vulkan.IndexType.Uint32);
|
Gd.Api.CmdBindIndexBuffer(CommandBuffer, buffer.Get(Cbs, 0, indexCount * sizeof(int)).Value, 0, Silk.NET.Vulkan.IndexType.Uint32);
|
||||||
|
|
||||||
@ -435,7 +438,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void DrawIndexedIndirect(BufferRange indirectBuffer)
|
public void DrawIndexedIndirect(BufferRange indirectBuffer)
|
||||||
{
|
{
|
||||||
var buffer = Gd.BufferManager
|
Buffer buffer = Gd.BufferManager
|
||||||
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
|
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
|
||||||
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
|
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
|
||||||
|
|
||||||
@ -481,11 +484,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void DrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
public void DrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
||||||
{
|
{
|
||||||
var countBuffer = Gd.BufferManager
|
Buffer countBuffer = Gd.BufferManager
|
||||||
.GetBuffer(CommandBuffer, parameterBuffer.Handle, parameterBuffer.Offset, parameterBuffer.Size, false)
|
.GetBuffer(CommandBuffer, parameterBuffer.Handle, parameterBuffer.Offset, parameterBuffer.Size, false)
|
||||||
.Get(Cbs, parameterBuffer.Offset, parameterBuffer.Size).Value;
|
.Get(Cbs, parameterBuffer.Offset, parameterBuffer.Size).Value;
|
||||||
|
|
||||||
var buffer = Gd.BufferManager
|
Buffer buffer = Gd.BufferManager
|
||||||
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
|
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
|
||||||
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
|
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
|
||||||
|
|
||||||
@ -575,7 +578,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
// TODO: Support quads and other unsupported topologies.
|
// TODO: Support quads and other unsupported topologies.
|
||||||
|
|
||||||
var buffer = Gd.BufferManager
|
Buffer buffer = Gd.BufferManager
|
||||||
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
|
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
|
||||||
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size, false).Value;
|
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size, false).Value;
|
||||||
|
|
||||||
@ -599,11 +602,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer = Gd.BufferManager
|
Buffer buffer = Gd.BufferManager
|
||||||
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
|
.GetBuffer(CommandBuffer, indirectBuffer.Handle, indirectBuffer.Offset, indirectBuffer.Size, false)
|
||||||
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size, false).Value;
|
.Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size, false).Value;
|
||||||
|
|
||||||
var countBuffer = Gd.BufferManager
|
Buffer countBuffer = Gd.BufferManager
|
||||||
.GetBuffer(CommandBuffer, parameterBuffer.Handle, parameterBuffer.Offset, parameterBuffer.Size, false)
|
.GetBuffer(CommandBuffer, parameterBuffer.Handle, parameterBuffer.Offset, parameterBuffer.Size, false)
|
||||||
.Get(Cbs, parameterBuffer.Offset, parameterBuffer.Size, false).Value;
|
.Get(Cbs, parameterBuffer.Offset, parameterBuffer.Size, false).Value;
|
||||||
|
|
||||||
@ -632,13 +635,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (texture is TextureView srcTexture)
|
if (texture is TextureView srcTexture)
|
||||||
{
|
{
|
||||||
var oldCullMode = _newState.CullMode;
|
CullModeFlags oldCullMode = _newState.CullMode;
|
||||||
var oldStencilTestEnable = _newState.StencilTestEnable;
|
bool oldStencilTestEnable = _newState.StencilTestEnable;
|
||||||
var oldDepthTestEnable = _newState.DepthTestEnable;
|
bool oldDepthTestEnable = _newState.DepthTestEnable;
|
||||||
var oldDepthWriteEnable = _newState.DepthWriteEnable;
|
bool oldDepthWriteEnable = _newState.DepthWriteEnable;
|
||||||
var oldViewports = DynamicState.Viewports;
|
Array16<Silk.NET.Vulkan.Viewport> oldViewports = DynamicState.Viewports;
|
||||||
var oldViewportsCount = _newState.ViewportsCount;
|
uint oldViewportsCount = _newState.ViewportsCount;
|
||||||
var oldTopology = _topology;
|
PrimitiveTopology oldTopology = _topology;
|
||||||
|
|
||||||
_newState.CullMode = CullModeFlags.None;
|
_newState.CullMode = CullModeFlags.None;
|
||||||
_newState.StencilTestEnable = false;
|
_newState.StencilTestEnable = false;
|
||||||
@ -710,11 +713,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
for (int index = 0; index < Constants.MaxRenderTargets; index++)
|
for (int index = 0; index < Constants.MaxRenderTargets; index++)
|
||||||
{
|
{
|
||||||
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
ref PipelineColorBlendAttachmentState vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
||||||
|
|
||||||
if (index == 0)
|
if (index == 0)
|
||||||
{
|
{
|
||||||
var blendOp = blend.Op.Convert();
|
BlendOp blendOp = blend.Op.Convert();
|
||||||
|
|
||||||
vkBlend = new PipelineColorBlendAttachmentState(
|
vkBlend = new PipelineColorBlendAttachmentState(
|
||||||
blendEnable: true,
|
blendEnable: true,
|
||||||
@ -751,7 +754,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void SetBlendState(int index, BlendDescriptor blend)
|
public void SetBlendState(int index, BlendDescriptor blend)
|
||||||
{
|
{
|
||||||
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
ref PipelineColorBlendAttachmentState vkBlend = ref _newState.Internal.ColorBlendAttachmentState[index];
|
||||||
|
|
||||||
if (blend.Enable)
|
if (blend.Enable)
|
||||||
{
|
{
|
||||||
@ -919,7 +922,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
_topology = topology;
|
_topology = topology;
|
||||||
|
|
||||||
var vkTopology = Gd.TopologyRemap(topology).Convert();
|
Silk.NET.Vulkan.PrimitiveTopology vkTopology = Gd.TopologyRemap(topology).Convert();
|
||||||
|
|
||||||
_newState.Topology = vkTopology;
|
_newState.Topology = vkTopology;
|
||||||
|
|
||||||
@ -928,8 +931,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void SetProgram(IProgram program)
|
public void SetProgram(IProgram program)
|
||||||
{
|
{
|
||||||
var internalProgram = (ShaderCollection)program;
|
ShaderCollection internalProgram = (ShaderCollection)program;
|
||||||
var stages = internalProgram.GetInfos();
|
PipelineShaderStageCreateInfo[] stages = internalProgram.GetInfos();
|
||||||
|
|
||||||
_program = internalProgram;
|
_program = internalProgram;
|
||||||
|
|
||||||
@ -952,7 +955,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void Specialize<T>(in T data) where T : unmanaged
|
public void Specialize<T>(in T data) where T : unmanaged
|
||||||
{
|
{
|
||||||
var dataSpan = MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in data), 1));
|
ReadOnlySpan<byte> dataSpan = MemoryMarshal.AsBytes(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(in data), 1));
|
||||||
|
|
||||||
if (!dataSpan.SequenceEqual(_newState.SpecializationData.Span))
|
if (!dataSpan.SequenceEqual(_newState.SpecializationData.Span))
|
||||||
{
|
{
|
||||||
@ -986,8 +989,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
|
ref PipelineColorBlendAttachmentState vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
|
||||||
var newMask = (ColorComponentFlags)componentMask[i];
|
ColorComponentFlags newMask = (ColorComponentFlags)componentMask[i];
|
||||||
|
|
||||||
// When color write mask is 0, remove all blend state to help the pipeline cache.
|
// When color write mask is 0, remove all blend state to help the pipeline cache.
|
||||||
// Restore it when the mask becomes non-zero.
|
// Restore it when the mask becomes non-zero.
|
||||||
@ -1054,9 +1057,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var region = regions[i];
|
Rectangle<int> region = regions[i];
|
||||||
var offset = new Offset2D(region.X, region.Y);
|
Offset2D offset = new Offset2D(region.X, region.Y);
|
||||||
var extent = new Extent2D((uint)region.Width, (uint)region.Height);
|
Extent2D extent = new Extent2D((uint)region.Width, (uint)region.Height);
|
||||||
|
|
||||||
DynamicState.SetScissor(i, new Rect2D(offset, extent));
|
DynamicState.SetScissor(i, new Rect2D(offset, extent));
|
||||||
}
|
}
|
||||||
@ -1129,7 +1132,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var range = buffers[i];
|
BufferRange range = buffers[i];
|
||||||
|
|
||||||
_transformFeedbackBuffers[i].Dispose();
|
_transformFeedbackBuffers[i].Dispose();
|
||||||
|
|
||||||
@ -1158,7 +1161,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
||||||
{
|
{
|
||||||
var formatCapabilities = Gd.FormatCapabilities;
|
FormatCapabilities formatCapabilities = Gd.FormatCapabilities;
|
||||||
|
|
||||||
Span<int> newVbScalarSizes = stackalloc int[Constants.MaxVertexBuffers];
|
Span<int> newVbScalarSizes = stackalloc int[Constants.MaxVertexBuffers];
|
||||||
|
|
||||||
@ -1167,9 +1170,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var attribute = vertexAttribs[i];
|
VertexAttribDescriptor attribute = vertexAttribs[i];
|
||||||
var rawIndex = attribute.BufferIndex;
|
int rawIndex = attribute.BufferIndex;
|
||||||
var bufferIndex = attribute.IsZero ? 0 : rawIndex + 1;
|
int bufferIndex = attribute.IsZero ? 0 : rawIndex + 1;
|
||||||
|
|
||||||
if (!attribute.IsZero)
|
if (!attribute.IsZero)
|
||||||
{
|
{
|
||||||
@ -1188,7 +1191,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
int dirtyBit = BitOperations.TrailingZeroCount(dirtyVbSizes);
|
int dirtyBit = BitOperations.TrailingZeroCount(dirtyVbSizes);
|
||||||
|
|
||||||
ref var buffer = ref _vertexBuffers[dirtyBit + 1];
|
ref VertexBufferState buffer = ref _vertexBuffers[dirtyBit + 1];
|
||||||
|
|
||||||
if (buffer.AttributeScalarAlignment != newVbScalarSizes[dirtyBit])
|
if (buffer.AttributeScalarAlignment != newVbScalarSizes[dirtyBit])
|
||||||
{
|
{
|
||||||
@ -1216,10 +1219,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var vertexBuffer = vertexBuffers[i];
|
VertexBufferDescriptor vertexBuffer = vertexBuffers[i];
|
||||||
|
|
||||||
// TODO: Support divisor > 1
|
// TODO: Support divisor > 1
|
||||||
var inputRate = vertexBuffer.Divisor != 0 ? VertexInputRate.Instance : VertexInputRate.Vertex;
|
VertexInputRate inputRate = vertexBuffer.Divisor != 0 ? VertexInputRate.Instance : VertexInputRate.Vertex;
|
||||||
|
|
||||||
if (vertexBuffer.Buffer.Handle != BufferHandle.Null)
|
if (vertexBuffer.Buffer.Handle != BufferHandle.Null)
|
||||||
{
|
{
|
||||||
@ -1253,7 +1256,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ref var buffer = ref _vertexBuffers[binding];
|
ref VertexBufferState buffer = ref _vertexBuffers[binding];
|
||||||
int oldScalarAlign = buffer.AttributeScalarAlignment;
|
int oldScalarAlign = buffer.AttributeScalarAlignment;
|
||||||
|
|
||||||
if (Gd.Capabilities.VertexBufferAlignment < 2 &&
|
if (Gd.Capabilities.VertexBufferAlignment < 2 &&
|
||||||
@ -1314,7 +1317,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var viewport = viewports[i];
|
Viewport viewport = viewports[i];
|
||||||
|
|
||||||
DynamicState.SetViewport(i, new Silk.NET.Vulkan.Viewport(
|
DynamicState.SetViewport(i, new Silk.NET.Vulkan.Viewport(
|
||||||
viewport.Region.X,
|
viewport.Region.X,
|
||||||
@ -1410,7 +1413,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref var vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
|
ref PipelineColorBlendAttachmentState vkBlend = ref _newState.Internal.ColorBlendAttachmentState[i];
|
||||||
|
|
||||||
for (int j = 0; j < i; j++)
|
for (int j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
@ -1419,7 +1422,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
if (colors[i] == colors[j])
|
if (colors[i] == colors[j])
|
||||||
{
|
{
|
||||||
// Prefer the binding with no write mask.
|
// Prefer the binding with no write mask.
|
||||||
ref var vkBlend2 = ref _newState.Internal.ColorBlendAttachmentState[j];
|
ref PipelineColorBlendAttachmentState vkBlend2 = ref _newState.Internal.ColorBlendAttachmentState[j];
|
||||||
if (vkBlend.ColorWriteMask == 0)
|
if (vkBlend.ColorWriteMask == 0)
|
||||||
{
|
{
|
||||||
colors[i] = null;
|
colors[i] = null;
|
||||||
@ -1457,7 +1460,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
protected void UpdatePipelineAttachmentFormats()
|
protected void UpdatePipelineAttachmentFormats()
|
||||||
{
|
{
|
||||||
var dstAttachmentFormats = _newState.Internal.AttachmentFormats.AsSpan();
|
Span<Silk.NET.Vulkan.Format> dstAttachmentFormats = _newState.Internal.AttachmentFormats.AsSpan();
|
||||||
FramebufferParams.AttachmentFormats.CopyTo(dstAttachmentFormats);
|
FramebufferParams.AttachmentFormats.CopyTo(dstAttachmentFormats);
|
||||||
_newState.Internal.AttachmentIntegerFormatMask = FramebufferParams.AttachmentIntegerFormatMask;
|
_newState.Internal.AttachmentIntegerFormatMask = FramebufferParams.AttachmentIntegerFormatMask;
|
||||||
_newState.Internal.LogicOpsAllowed = FramebufferParams.LogicOpsAllowed;
|
_newState.Internal.LogicOpsAllowed = FramebufferParams.LogicOpsAllowed;
|
||||||
@ -1474,7 +1477,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
protected unsafe void CreateRenderPass()
|
protected unsafe void CreateRenderPass()
|
||||||
{
|
{
|
||||||
var hasFramebuffer = FramebufferParams != null;
|
bool hasFramebuffer = FramebufferParams != null;
|
||||||
|
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
|
||||||
@ -1679,7 +1682,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipeline = pbp == PipelineBindPoint.Compute
|
Auto<DisposablePipeline> pipeline = pbp == PipelineBindPoint.Compute
|
||||||
? _newState.CreateComputePipeline(Gd, Device, _program, PipelineCache)
|
? _newState.CreateComputePipeline(Gd, Device, _program, PipelineCache)
|
||||||
: _newState.CreateGraphicsPipeline(Gd, Device, _program, PipelineCache, _renderPass.Get(Cbs).Value);
|
: _newState.CreateGraphicsPipeline(Gd, Device, _program, PipelineCache, _renderPass.Get(Cbs).Value);
|
||||||
|
|
||||||
@ -1711,10 +1714,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
FramebufferParams.InsertLoadOpBarriers(Gd, Cbs);
|
FramebufferParams.InsertLoadOpBarriers(Gd, Cbs);
|
||||||
|
|
||||||
var renderArea = new Rect2D(null, new Extent2D(FramebufferParams.Width, FramebufferParams.Height));
|
Rect2D renderArea = new Rect2D(null, new Extent2D(FramebufferParams.Width, FramebufferParams.Height));
|
||||||
var clearValue = new ClearValue();
|
ClearValue clearValue = new ClearValue();
|
||||||
|
|
||||||
var renderPassBeginInfo = new RenderPassBeginInfo
|
RenderPassBeginInfo renderPassBeginInfo = new RenderPassBeginInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassBeginInfo,
|
SType = StructureType.RenderPassBeginInfo,
|
||||||
RenderPass = _renderPass.Get(Cbs).Value,
|
RenderPass = _renderPass.Get(Cbs).Value,
|
||||||
|
@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
AttachmentDescription[] attachmentDescs = null;
|
AttachmentDescription[] attachmentDescs = null;
|
||||||
|
|
||||||
var subpass = new SubpassDescription
|
SubpassDescription subpass = new SubpassDescription
|
||||||
{
|
{
|
||||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||||
};
|
};
|
||||||
@ -107,11 +107,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var subpassDependency = CreateSubpassDependency(gd);
|
SubpassDependency subpassDependency = CreateSubpassDependency(gd);
|
||||||
|
|
||||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||||
{
|
{
|
||||||
var renderPassCreateInfo = new RenderPassCreateInfo
|
RenderPassCreateInfo renderPassCreateInfo = new RenderPassCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassCreateInfo,
|
SType = StructureType.RenderPassCreateInfo,
|
||||||
PAttachments = pAttachmentDescs,
|
PAttachments = pAttachmentDescs,
|
||||||
@ -122,7 +122,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
DependencyCount = 1,
|
DependencyCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateRenderPass(device, in renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
gd.Api.CreateRenderPass(device, in renderPassCreateInfo, null, out RenderPass renderPass).ThrowOnError();
|
||||||
|
|
||||||
return new DisposableRenderPass(gd.Api, device, renderPass);
|
return new DisposableRenderPass(gd.Api, device, renderPass);
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public static SubpassDependency CreateSubpassDependency(VulkanRenderer gd)
|
public static SubpassDependency CreateSubpassDependency(VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
var (access, stages) = BarrierBatch.GetSubpassAccessSuperset(gd);
|
(AccessFlags access, PipelineStageFlags stages) = BarrierBatch.GetSubpassAccessSuperset(gd);
|
||||||
|
|
||||||
return new SubpassDependency(
|
return new SubpassDependency(
|
||||||
0,
|
0,
|
||||||
@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public unsafe static SubpassDependency2 CreateSubpassDependency2(VulkanRenderer gd)
|
public unsafe static SubpassDependency2 CreateSubpassDependency2(VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
var (access, stages) = BarrierBatch.GetSubpassAccessSuperset(gd);
|
(AccessFlags access, PipelineStageFlags stages) = BarrierBatch.GetSubpassAccessSuperset(gd);
|
||||||
|
|
||||||
return new SubpassDependency2(
|
return new SubpassDependency2(
|
||||||
StructureType.SubpassDependency2,
|
StructureType.SubpassDependency2,
|
||||||
@ -225,8 +225,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < vaCount; i++)
|
for (int i = 0; i < vaCount; i++)
|
||||||
{
|
{
|
||||||
var attribute = state.VertexAttribs[i];
|
VertexAttribDescriptor attribute = state.VertexAttribs[i];
|
||||||
var bufferIndex = attribute.IsZero ? 0 : attribute.BufferIndex + 1;
|
int bufferIndex = attribute.IsZero ? 0 : attribute.BufferIndex + 1;
|
||||||
|
|
||||||
pipeline.Internal.VertexAttributeDescriptions[i] = new VertexInputAttributeDescription(
|
pipeline.Internal.VertexAttributeDescriptions[i] = new VertexInputAttributeDescription(
|
||||||
(uint)i,
|
(uint)i,
|
||||||
@ -245,11 +245,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < vbCount; i++)
|
for (int i = 0; i < vbCount; i++)
|
||||||
{
|
{
|
||||||
var vertexBuffer = state.VertexBuffers[i];
|
BufferPipelineDescriptor vertexBuffer = state.VertexBuffers[i];
|
||||||
|
|
||||||
if (vertexBuffer.Enable)
|
if (vertexBuffer.Enable)
|
||||||
{
|
{
|
||||||
var inputRate = vertexBuffer.Divisor != 0 ? VertexInputRate.Instance : VertexInputRate.Vertex;
|
VertexInputRate inputRate = vertexBuffer.Divisor != 0 ? VertexInputRate.Instance : VertexInputRate.Vertex;
|
||||||
|
|
||||||
int alignedStride = vertexBuffer.Stride;
|
int alignedStride = vertexBuffer.Stride;
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < Constants.MaxRenderTargets; i++)
|
for (int i = 0; i < Constants.MaxRenderTargets; i++)
|
||||||
{
|
{
|
||||||
var blend = state.BlendDescriptors[i];
|
BlendDescriptor blend = state.BlendDescriptors[i];
|
||||||
|
|
||||||
if (blend.Enable && state.ColorWriteMask[i] != 0)
|
if (blend.Enable && state.ColorWriteMask[i] != 0)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void CopyPendingQuery()
|
private void CopyPendingQuery()
|
||||||
{
|
{
|
||||||
foreach (var query in _pendingQueryCopies)
|
foreach (BufferedQuery query in _pendingQueryCopies)
|
||||||
{
|
{
|
||||||
query.PoolCopy(Cbs);
|
query.PoolCopy(Cbs);
|
||||||
}
|
}
|
||||||
@ -54,7 +54,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// We can't use CmdClearAttachments if not writing all components,
|
// We can't use CmdClearAttachments if not writing all components,
|
||||||
// because on Vulkan, the pipeline state does not affect clears.
|
// because on Vulkan, the pipeline state does not affect clears.
|
||||||
// On proprietary Adreno drivers, CmdClearAttachments appears to execute out of order, so it's better to not use it at all.
|
// On proprietary Adreno drivers, CmdClearAttachments appears to execute out of order, so it's better to not use it at all.
|
||||||
var dstTexture = FramebufferParams.GetColorView(index);
|
TextureView dstTexture = FramebufferParams.GetColorView(index);
|
||||||
if (dstTexture == null)
|
if (dstTexture == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -95,7 +95,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// We can't use CmdClearAttachments if not clearing all (mask is all ones, 0xFF) or none (mask is 0) of the stencil bits,
|
// We can't use CmdClearAttachments if not clearing all (mask is all ones, 0xFF) or none (mask is 0) of the stencil bits,
|
||||||
// because on Vulkan, the pipeline state does not affect clears.
|
// because on Vulkan, the pipeline state does not affect clears.
|
||||||
// On proprietary Adreno drivers, CmdClearAttachments appears to execute out of order, so it's better to not use it at all.
|
// On proprietary Adreno drivers, CmdClearAttachments appears to execute out of order, so it's better to not use it at all.
|
||||||
var dstTexture = FramebufferParams.GetDepthStencilView();
|
TextureView dstTexture = FramebufferParams.GetDepthStencilView();
|
||||||
if (dstTexture == null)
|
if (dstTexture == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -246,7 +246,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
AutoFlush.RegisterFlush(DrawCount);
|
AutoFlush.RegisterFlush(DrawCount);
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
|
|
||||||
foreach ((var queryPool, _) in _activeQueries)
|
foreach ((QueryPool queryPool, _) in _activeQueries)
|
||||||
{
|
{
|
||||||
Gd.Api.CmdEndQuery(CommandBuffer, queryPool, 0);
|
Gd.Api.CmdEndQuery(CommandBuffer, queryPool, 0);
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_activeBufferMirrors.Clear();
|
_activeBufferMirrors.Clear();
|
||||||
|
|
||||||
foreach ((var queryPool, var isOcclusion) in _activeQueries)
|
foreach ((QueryPool queryPool, bool isOcclusion) in _activeQueries)
|
||||||
{
|
{
|
||||||
bool isPrecise = Gd.Capabilities.SupportsPreciseOcclusionQueries && isOcclusion;
|
bool isPrecise = Gd.Capabilities.SupportsPreciseOcclusionQueries && isOcclusion;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (SetDescriptors != null)
|
if (SetDescriptors != null)
|
||||||
{
|
{
|
||||||
foreach (var setDescriptor in SetDescriptors)
|
foreach (ResourceDescriptorCollection setDescriptor in SetDescriptors)
|
||||||
{
|
{
|
||||||
hasher.Add(setDescriptor);
|
hasher.Add(setDescriptor);
|
||||||
}
|
}
|
||||||
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ReadOnlyCollection<ResourceDescriptorCollection> setDescriptors,
|
ReadOnlyCollection<ResourceDescriptorCollection> setDescriptors,
|
||||||
bool usePushDescriptors)
|
bool usePushDescriptors)
|
||||||
{
|
{
|
||||||
var key = new PlceKey(setDescriptors, usePushDescriptors);
|
PlceKey key = new PlceKey(setDescriptors, usePushDescriptors);
|
||||||
|
|
||||||
return _plces.GetOrAdd(key, newKey => new PipelineLayoutCacheEntry(gd, device, setDescriptors, usePushDescriptors));
|
return _plces.GetOrAdd(key, newKey => new PipelineLayoutCacheEntry(gd, device, setDescriptors, usePushDescriptors));
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
foreach (var plce in _plces.Values)
|
foreach (PipelineLayoutCacheEntry plce in _plces.Values)
|
||||||
{
|
{
|
||||||
plce.Dispose();
|
plce.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
foreach (var descriptor in setDescriptors[setIndex].Descriptors)
|
foreach (ResourceDescriptor descriptor in setDescriptors[setIndex].Descriptors)
|
||||||
{
|
{
|
||||||
count += descriptor.Count;
|
count += descriptor.Count;
|
||||||
}
|
}
|
||||||
@ -148,11 +148,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DescriptorSetCollection> GetNewDescriptorSetCollection(int setIndex, out bool isNew)
|
public Auto<DescriptorSetCollection> GetNewDescriptorSetCollection(int setIndex, out bool isNew)
|
||||||
{
|
{
|
||||||
var list = _currentDsCache[setIndex];
|
List<Auto<DescriptorSetCollection>> list = _currentDsCache[setIndex];
|
||||||
int index = _dsCacheCursor[setIndex]++;
|
int index = _dsCacheCursor[setIndex]++;
|
||||||
if (index == list.Count)
|
if (index == list.Count)
|
||||||
{
|
{
|
||||||
var dsc = _descriptorSetManager.AllocateDescriptorSet(
|
Auto<DescriptorSetCollection> dsc = _descriptorSetManager.AllocateDescriptorSet(
|
||||||
_gd.Api,
|
_gd.Api,
|
||||||
DescriptorSetLayouts[setIndex],
|
DescriptorSetLayouts[setIndex],
|
||||||
_poolSizes[setIndex],
|
_poolSizes[setIndex],
|
||||||
@ -173,8 +173,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
FreeCompletedManualDescriptorSets();
|
FreeCompletedManualDescriptorSets();
|
||||||
|
|
||||||
var list = _manualDsCache[setIndex] ??= new();
|
List<ManualDescriptorSetEntry> list = _manualDsCache[setIndex] ??= new();
|
||||||
var span = CollectionsMarshal.AsSpan(list);
|
Span<ManualDescriptorSetEntry> span = CollectionsMarshal.AsSpan(list);
|
||||||
|
|
||||||
Queue<int> freeQueue = _freeManualDsCacheEntries[setIndex];
|
Queue<int> freeQueue = _freeManualDsCacheEntries[setIndex];
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise create a new descriptor set, and add to our pending queue for command buffer consumption tracking.
|
// Otherwise create a new descriptor set, and add to our pending queue for command buffer consumption tracking.
|
||||||
var dsc = _descriptorSetManager.AllocateDescriptorSet(
|
Auto<DescriptorSetCollection> dsc = _descriptorSetManager.AllocateDescriptorSet(
|
||||||
_gd.Api,
|
_gd.Api,
|
||||||
DescriptorSetLayouts[setIndex],
|
DescriptorSetLayouts[setIndex],
|
||||||
_poolSizes[setIndex],
|
_poolSizes[setIndex],
|
||||||
@ -214,9 +214,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
FreeCompletedManualDescriptorSets();
|
FreeCompletedManualDescriptorSets();
|
||||||
|
|
||||||
var list = _manualDsCache[setIndex];
|
List<ManualDescriptorSetEntry> list = _manualDsCache[setIndex];
|
||||||
var span = CollectionsMarshal.AsSpan(list);
|
Span<ManualDescriptorSetEntry> span = CollectionsMarshal.AsSpan(list);
|
||||||
ref var entry = ref span[cacheIndex];
|
ref ManualDescriptorSetEntry entry = ref span[cacheIndex];
|
||||||
|
|
||||||
uint cbMask = 1u << cbs.CommandBufferIndex;
|
uint cbMask = 1u << cbs.CommandBufferIndex;
|
||||||
|
|
||||||
@ -231,15 +231,15 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
private void FreeCompletedManualDescriptorSets()
|
private void FreeCompletedManualDescriptorSets()
|
||||||
{
|
{
|
||||||
FenceHolder signalledFence = null;
|
FenceHolder signalledFence = null;
|
||||||
while (_pendingManualDsConsumptions.TryPeek(out var pds) && (pds.Fence == signalledFence || pds.Fence.IsSignaled()))
|
while (_pendingManualDsConsumptions.TryPeek(out PendingManualDsConsumption pds) && (pds.Fence == signalledFence || pds.Fence.IsSignaled()))
|
||||||
{
|
{
|
||||||
signalledFence = pds.Fence; // Already checked - don't need to do it again.
|
signalledFence = pds.Fence; // Already checked - don't need to do it again.
|
||||||
var dequeued = _pendingManualDsConsumptions.Dequeue();
|
PendingManualDsConsumption dequeued = _pendingManualDsConsumptions.Dequeue();
|
||||||
Debug.Assert(dequeued.Fence == pds.Fence);
|
Debug.Assert(dequeued.Fence == pds.Fence);
|
||||||
pds.Fence.Put();
|
pds.Fence.Put();
|
||||||
|
|
||||||
var span = CollectionsMarshal.AsSpan(_manualDsCache[dequeued.SetIndex]);
|
Span<ManualDescriptorSetEntry> span = CollectionsMarshal.AsSpan(_manualDsCache[dequeued.SetIndex]);
|
||||||
ref var entry = ref span[dequeued.CacheIndex];
|
ref ManualDescriptorSetEntry entry = ref span[dequeued.CacheIndex];
|
||||||
entry.CbRefMask &= ~(1u << dequeued.CommandBufferIndex);
|
entry.CbRefMask &= ~(1u << dequeued.CommandBufferIndex);
|
||||||
|
|
||||||
if (!entry.InUse && entry.CbRefMask == 0)
|
if (!entry.InUse && entry.CbRefMask == 0)
|
||||||
@ -252,8 +252,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void ReleaseManualDescriptorSetCollection(int setIndex, int cacheIndex)
|
public void ReleaseManualDescriptorSetCollection(int setIndex, int cacheIndex)
|
||||||
{
|
{
|
||||||
var list = _manualDsCache[setIndex];
|
List<ManualDescriptorSetEntry> list = _manualDsCache[setIndex];
|
||||||
var span = CollectionsMarshal.AsSpan(list);
|
Span<ManualDescriptorSetEntry> span = CollectionsMarshal.AsSpan(list);
|
||||||
|
|
||||||
span[cacheIndex].InUse = false;
|
span[cacheIndex].InUse = false;
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_gd.Api.DestroyDescriptorSetLayout(_device, DescriptorSetLayouts[i], null);
|
_gd.Api.DestroyDescriptorSetLayout(_device, DescriptorSetLayouts[i], null);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (_pendingManualDsConsumptions.TryDequeue(out var pds))
|
while (_pendingManualDsConsumptions.TryDequeue(out PendingManualDsConsumption pds))
|
||||||
{
|
{
|
||||||
pds.Fence.Put();
|
pds.Fence.Put();
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
updateAfterBindFlags[setIndex] = true;
|
updateAfterBindFlags[setIndex] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
|
DescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DescriptorSetLayoutCreateInfo,
|
SType = StructureType.DescriptorSetLayoutCreateInfo,
|
||||||
PBindings = pLayoutBindings,
|
PBindings = pLayoutBindings,
|
||||||
@ -99,7 +99,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
fixed (DescriptorSetLayout* pLayouts = layouts)
|
fixed (DescriptorSetLayout* pLayouts = layouts)
|
||||||
{
|
{
|
||||||
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo
|
PipelineLayoutCreateInfo pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineLayoutCreateInfo,
|
SType = StructureType.PipelineLayoutCreateInfo,
|
||||||
PSetLayouts = pLayouts,
|
PSetLayouts = pLayouts,
|
||||||
|
@ -333,12 +333,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ShaderCollection program,
|
ShaderCollection program,
|
||||||
PipelineCache cache)
|
PipelineCache cache)
|
||||||
{
|
{
|
||||||
if (program.TryGetComputePipeline(ref SpecializationData, out var pipeline))
|
if (program.TryGetComputePipeline(ref SpecializationData, out Auto<DisposablePipeline> pipeline))
|
||||||
{
|
{
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineCreateInfo = new ComputePipelineCreateInfo
|
ComputePipelineCreateInfo pipelineCreateInfo = new ComputePipelineCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ComputePipelineCreateInfo,
|
SType = StructureType.ComputePipelineCreateInfo,
|
||||||
Stage = Stages[0],
|
Stage = Stages[0],
|
||||||
@ -350,7 +350,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
bool hasSpec = program.SpecDescriptions != null;
|
bool hasSpec = program.SpecDescriptions != null;
|
||||||
|
|
||||||
var desc = hasSpec ? program.SpecDescriptions[0] : SpecDescription.Empty;
|
SpecDescription desc = hasSpec ? program.SpecDescriptions[0] : SpecDescription.Empty;
|
||||||
|
|
||||||
if (hasSpec && SpecializationData.Length < (int)desc.Info.DataSize)
|
if (hasSpec && SpecializationData.Length < (int)desc.Info.DataSize)
|
||||||
{
|
{
|
||||||
@ -386,7 +386,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
RenderPass renderPass,
|
RenderPass renderPass,
|
||||||
bool throwOnError = false)
|
bool throwOnError = false)
|
||||||
{
|
{
|
||||||
if (program.TryGetGraphicsPipeline(ref Internal, out var pipeline))
|
if (program.TryGetGraphicsPipeline(ref Internal, out Auto<DisposablePipeline> pipeline))
|
||||||
{
|
{
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
@ -405,7 +405,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
fixed (VertexInputBindingDescription* pVertexBindingDescriptions = &Internal.VertexBindingDescriptions[0])
|
fixed (VertexInputBindingDescription* pVertexBindingDescriptions = &Internal.VertexBindingDescriptions[0])
|
||||||
fixed (PipelineColorBlendAttachmentState* pColorBlendAttachmentState = &Internal.ColorBlendAttachmentState[0])
|
fixed (PipelineColorBlendAttachmentState* pColorBlendAttachmentState = &Internal.ColorBlendAttachmentState[0])
|
||||||
{
|
{
|
||||||
var vertexInputState = new PipelineVertexInputStateCreateInfo
|
PipelineVertexInputStateCreateInfo vertexInputState = new PipelineVertexInputStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineVertexInputStateCreateInfo,
|
SType = StructureType.PipelineVertexInputStateCreateInfo,
|
||||||
VertexAttributeDescriptionCount = VertexAttributeDescriptionsCount,
|
VertexAttributeDescriptionCount = VertexAttributeDescriptionsCount,
|
||||||
@ -442,20 +442,20 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
primitiveRestartEnable &= topologySupportsRestart;
|
primitiveRestartEnable &= topologySupportsRestart;
|
||||||
|
|
||||||
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
|
PipelineInputAssemblyStateCreateInfo inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
SType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
||||||
PrimitiveRestartEnable = primitiveRestartEnable,
|
PrimitiveRestartEnable = primitiveRestartEnable,
|
||||||
Topology = HasTessellationControlShader ? PrimitiveTopology.PatchList : Topology,
|
Topology = HasTessellationControlShader ? PrimitiveTopology.PatchList : Topology,
|
||||||
};
|
};
|
||||||
|
|
||||||
var tessellationState = new PipelineTessellationStateCreateInfo
|
PipelineTessellationStateCreateInfo tessellationState = new PipelineTessellationStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineTessellationStateCreateInfo,
|
SType = StructureType.PipelineTessellationStateCreateInfo,
|
||||||
PatchControlPoints = PatchControlPoints,
|
PatchControlPoints = PatchControlPoints,
|
||||||
};
|
};
|
||||||
|
|
||||||
var rasterizationState = new PipelineRasterizationStateCreateInfo
|
PipelineRasterizationStateCreateInfo rasterizationState = new PipelineRasterizationStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineRasterizationStateCreateInfo,
|
SType = StructureType.PipelineRasterizationStateCreateInfo,
|
||||||
DepthClampEnable = DepthClampEnable,
|
DepthClampEnable = DepthClampEnable,
|
||||||
@ -467,7 +467,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
DepthBiasEnable = DepthBiasEnable,
|
DepthBiasEnable = DepthBiasEnable,
|
||||||
};
|
};
|
||||||
|
|
||||||
var viewportState = new PipelineViewportStateCreateInfo
|
PipelineViewportStateCreateInfo viewportState = new PipelineViewportStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineViewportStateCreateInfo,
|
SType = StructureType.PipelineViewportStateCreateInfo,
|
||||||
ViewportCount = ViewportsCount,
|
ViewportCount = ViewportsCount,
|
||||||
@ -476,7 +476,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (gd.Capabilities.SupportsDepthClipControl)
|
if (gd.Capabilities.SupportsDepthClipControl)
|
||||||
{
|
{
|
||||||
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT
|
PipelineViewportDepthClipControlCreateInfoEXT viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt,
|
SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt,
|
||||||
NegativeOneToOne = DepthMode,
|
NegativeOneToOne = DepthMode,
|
||||||
@ -485,7 +485,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
viewportState.PNext = &viewportDepthClipControlState;
|
viewportState.PNext = &viewportDepthClipControlState;
|
||||||
}
|
}
|
||||||
|
|
||||||
var multisampleState = new PipelineMultisampleStateCreateInfo
|
PipelineMultisampleStateCreateInfo multisampleState = new PipelineMultisampleStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineMultisampleStateCreateInfo,
|
SType = StructureType.PipelineMultisampleStateCreateInfo,
|
||||||
SampleShadingEnable = false,
|
SampleShadingEnable = false,
|
||||||
@ -495,19 +495,19 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
AlphaToOneEnable = AlphaToOneEnable,
|
AlphaToOneEnable = AlphaToOneEnable,
|
||||||
};
|
};
|
||||||
|
|
||||||
var stencilFront = new StencilOpState(
|
StencilOpState stencilFront = new StencilOpState(
|
||||||
StencilFrontFailOp,
|
StencilFrontFailOp,
|
||||||
StencilFrontPassOp,
|
StencilFrontPassOp,
|
||||||
StencilFrontDepthFailOp,
|
StencilFrontDepthFailOp,
|
||||||
StencilFrontCompareOp);
|
StencilFrontCompareOp);
|
||||||
|
|
||||||
var stencilBack = new StencilOpState(
|
StencilOpState stencilBack = new StencilOpState(
|
||||||
StencilBackFailOp,
|
StencilBackFailOp,
|
||||||
StencilBackPassOp,
|
StencilBackPassOp,
|
||||||
StencilBackDepthFailOp,
|
StencilBackDepthFailOp,
|
||||||
StencilBackCompareOp);
|
StencilBackCompareOp);
|
||||||
|
|
||||||
var depthStencilState = new PipelineDepthStencilStateCreateInfo
|
PipelineDepthStencilStateCreateInfo depthStencilState = new PipelineDepthStencilStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineDepthStencilStateCreateInfo,
|
SType = StructureType.PipelineDepthStencilStateCreateInfo,
|
||||||
DepthTestEnable = DepthTestEnable,
|
DepthTestEnable = DepthTestEnable,
|
||||||
@ -544,7 +544,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// so we need to force disable them here.
|
// so we need to force disable them here.
|
||||||
bool logicOpEnable = LogicOpEnable && (gd.Vendor == Vendor.Nvidia || Internal.LogicOpsAllowed);
|
bool logicOpEnable = LogicOpEnable && (gd.Vendor == Vendor.Nvidia || Internal.LogicOpsAllowed);
|
||||||
|
|
||||||
var colorBlendState = new PipelineColorBlendStateCreateInfo
|
PipelineColorBlendStateCreateInfo colorBlendState = new PipelineColorBlendStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
||||||
LogicOpEnable = logicOpEnable,
|
LogicOpEnable = logicOpEnable,
|
||||||
@ -595,7 +595,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dynamicStates[dynamicStatesCount++] = DynamicState.AttachmentFeedbackLoopEnableExt;
|
dynamicStates[dynamicStatesCount++] = DynamicState.AttachmentFeedbackLoopEnableExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
PipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineDynamicStateCreateInfo,
|
SType = StructureType.PipelineDynamicStateCreateInfo,
|
||||||
DynamicStateCount = (uint)dynamicStatesCount,
|
DynamicStateCount = (uint)dynamicStatesCount,
|
||||||
@ -619,7 +619,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineCreateInfo = new GraphicsPipelineCreateInfo
|
GraphicsPipelineCreateInfo pipelineCreateInfo = new GraphicsPipelineCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.GraphicsPipelineCreateInfo,
|
SType = StructureType.GraphicsPipelineCreateInfo,
|
||||||
Flags = flags,
|
Flags = flags,
|
||||||
@ -677,12 +677,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int index = 0; index < VertexAttributeDescriptionsCount; index++)
|
for (int index = 0; index < VertexAttributeDescriptionsCount; index++)
|
||||||
{
|
{
|
||||||
var attribute = Internal.VertexAttributeDescriptions[index];
|
VertexInputAttributeDescription attribute = Internal.VertexAttributeDescriptions[index];
|
||||||
int vbIndex = GetVertexBufferIndex(attribute.Binding);
|
int vbIndex = GetVertexBufferIndex(attribute.Binding);
|
||||||
|
|
||||||
if (vbIndex >= 0)
|
if (vbIndex >= 0)
|
||||||
{
|
{
|
||||||
ref var vb = ref Internal.VertexBindingDescriptions[vbIndex];
|
ref VertexInputBindingDescription vb = ref Internal.VertexBindingDescriptions[vbIndex];
|
||||||
|
|
||||||
Format format = attribute.Format;
|
Format format = attribute.Format;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ using Silk.NET.Vulkan;
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan.Queries
|
namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
{
|
{
|
||||||
@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
QueryPipelineStatisticFlags flags = type == CounterType.PrimitivesGenerated ?
|
QueryPipelineStatisticFlags flags = type == CounterType.PrimitivesGenerated ?
|
||||||
QueryPipelineStatisticFlags.GeometryShaderPrimitivesBit : 0;
|
QueryPipelineStatisticFlags.GeometryShaderPrimitivesBit : 0;
|
||||||
|
|
||||||
var queryPoolCreateInfo = new QueryPoolCreateInfo
|
QueryPoolCreateInfo queryPoolCreateInfo = new QueryPoolCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.QueryPoolCreateInfo,
|
SType = StructureType.QueryPoolCreateInfo,
|
||||||
QueryCount = 1,
|
QueryCount = 1,
|
||||||
@ -55,7 +56,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
gd.Api.CreateQueryPool(device, in queryPoolCreateInfo, null, out _queryPool).ThrowOnError();
|
gd.Api.CreateQueryPool(device, in queryPoolCreateInfo, null, out _queryPool).ThrowOnError();
|
||||||
}
|
}
|
||||||
|
|
||||||
var buffer = gd.BufferManager.Create(gd, sizeof(long), forConditionalRendering: true);
|
BufferHolder buffer = gd.BufferManager.Create(gd, sizeof(long), forConditionalRendering: true);
|
||||||
|
|
||||||
_bufferMap = buffer.Map(0, sizeof(long));
|
_bufferMap = buffer.Map(0, sizeof(long));
|
||||||
_defaultValue = result32Bit ? DefaultValueInt : DefaultValue;
|
_defaultValue = result32Bit ? DefaultValueInt : DefaultValue;
|
||||||
@ -183,7 +184,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
|
|
||||||
public void PoolCopy(CommandBufferScoped cbs)
|
public void PoolCopy(CommandBufferScoped cbs)
|
||||||
{
|
{
|
||||||
var buffer = _buffer.GetBuffer(cbs.CommandBuffer, true).Get(cbs, 0, sizeof(long), true).Value;
|
Buffer buffer = _buffer.GetBuffer(cbs.CommandBuffer, true).Get(cbs, 0, sizeof(long), true).Value;
|
||||||
|
|
||||||
QueryResultFlags flags = QueryResultFlags.ResultWaitBit;
|
QueryResultFlags flags = QueryResultFlags.ResultWaitBit;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
|
|
||||||
public void ResetCounterPool()
|
public void ResetCounterPool()
|
||||||
{
|
{
|
||||||
foreach (var queue in _counterQueues)
|
foreach (CounterQueue queue in _counterQueues)
|
||||||
{
|
{
|
||||||
queue.ResetCounterPool();
|
queue.ResetCounterPool();
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
foreach (var queue in _counterQueues)
|
foreach (CounterQueue queue in _counterQueues)
|
||||||
{
|
{
|
||||||
queue.Flush(false);
|
queue.Flush(false);
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
foreach (var queue in _counterQueues)
|
foreach (CounterQueue queue in _counterQueues)
|
||||||
{
|
{
|
||||||
queue.Dispose();
|
queue.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (_colors != null)
|
if (_colors != null)
|
||||||
{
|
{
|
||||||
foreach (var color in _colors)
|
foreach (TextureView color in _colors)
|
||||||
{
|
{
|
||||||
hc.Add(color);
|
hc.Add(color);
|
||||||
}
|
}
|
||||||
|
@ -47,14 +47,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
AttachmentDescription[] attachmentDescs = null;
|
AttachmentDescription[] attachmentDescs = null;
|
||||||
|
|
||||||
var subpass = new SubpassDescription
|
SubpassDescription subpass = new SubpassDescription
|
||||||
{
|
{
|
||||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||||
};
|
};
|
||||||
|
|
||||||
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
||||||
|
|
||||||
var hasFramebuffer = fb != null;
|
bool hasFramebuffer = fb != null;
|
||||||
|
|
||||||
if (hasFramebuffer && fb.AttachmentsCount != 0)
|
if (hasFramebuffer && fb.AttachmentsCount != 0)
|
||||||
{
|
{
|
||||||
@ -110,11 +110,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var subpassDependency = PipelineConverter.CreateSubpassDependency(gd);
|
SubpassDependency subpassDependency = PipelineConverter.CreateSubpassDependency(gd);
|
||||||
|
|
||||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||||
{
|
{
|
||||||
var renderPassCreateInfo = new RenderPassCreateInfo
|
RenderPassCreateInfo renderPassCreateInfo = new RenderPassCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassCreateInfo,
|
SType = StructureType.RenderPassCreateInfo,
|
||||||
PAttachments = pAttachmentDescs,
|
PAttachments = pAttachmentDescs,
|
||||||
@ -125,7 +125,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
DependencyCount = 1,
|
DependencyCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateRenderPass(device, in renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
gd.Api.CreateRenderPass(device, in renderPassCreateInfo, null, out RenderPass renderPass).ThrowOnError();
|
||||||
|
|
||||||
_renderPass = new Auto<DisposableRenderPass>(new DisposableRenderPass(gd.Api, device, renderPass));
|
_renderPass = new Auto<DisposableRenderPass>(new DisposableRenderPass(gd.Api, device, renderPass));
|
||||||
}
|
}
|
||||||
@ -134,9 +134,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
// Register this render pass with all render target views.
|
// Register this render pass with all render target views.
|
||||||
|
|
||||||
var textures = fb.GetAttachmentViews();
|
TextureView[] textures = fb.GetAttachmentViews();
|
||||||
|
|
||||||
foreach (var texture in textures)
|
foreach (TextureView texture in textures)
|
||||||
{
|
{
|
||||||
texture.AddRenderPass(key, this);
|
texture.AddRenderPass(key, this);
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public Auto<DisposableFramebuffer> GetFramebuffer(VulkanRenderer gd, CommandBufferScoped cbs, FramebufferParams fb)
|
public Auto<DisposableFramebuffer> GetFramebuffer(VulkanRenderer gd, CommandBufferScoped cbs, FramebufferParams fb)
|
||||||
{
|
{
|
||||||
var key = new FramebufferCacheKey(fb.Width, fb.Height, fb.Layers);
|
FramebufferCacheKey key = new FramebufferCacheKey(fb.Width, fb.Height, fb.Layers);
|
||||||
|
|
||||||
if (!_framebuffers.TryGetValue(ref key, out Auto<DisposableFramebuffer> result))
|
if (!_framebuffers.TryGetValue(ref key, out Auto<DisposableFramebuffer> result))
|
||||||
{
|
{
|
||||||
@ -201,14 +201,14 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
// Dispose all framebuffers.
|
// Dispose all framebuffers.
|
||||||
|
|
||||||
foreach (var fb in _framebuffers.Values)
|
foreach (Auto<DisposableFramebuffer> fb in _framebuffers.Values)
|
||||||
{
|
{
|
||||||
fb.Dispose();
|
fb.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify all texture views that this render pass has been disposed.
|
// Notify all texture views that this render pass has been disposed.
|
||||||
|
|
||||||
foreach (var texture in _textures)
|
foreach (TextureView texture in _textures)
|
||||||
{
|
{
|
||||||
texture.RemoveRenderPass(_key);
|
texture.RemoveRenderPass(_key);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dsc = program.GetNewManualDescriptorSetCollection(cbs, setIndex, out _cachedDscIndex).Get(cbs);
|
DescriptorSetCollection dsc = program.GetNewManualDescriptorSetCollection(cbs, setIndex, out _cachedDscIndex).Get(cbs);
|
||||||
|
|
||||||
sets = dsc.GetSets();
|
sets = dsc.GetSets();
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public ResourceLayout Build()
|
public ResourceLayout Build()
|
||||||
{
|
{
|
||||||
var descriptors = new ResourceDescriptorCollection[TotalSets];
|
ResourceDescriptorCollection[] descriptors = new ResourceDescriptorCollection[TotalSets];
|
||||||
var usages = new ResourceUsageCollection[TotalSets];
|
ResourceUsageCollection[] usages = new ResourceUsageCollection[TotalSets];
|
||||||
|
|
||||||
for (int index = 0; index < TotalSets; index++)
|
for (int index = 0; index < TotalSets; index++)
|
||||||
{
|
{
|
||||||
|
@ -26,9 +26,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
maxLod = 0.25f;
|
maxLod = 0.25f;
|
||||||
}
|
}
|
||||||
|
|
||||||
var borderColor = GetConstrainedBorderColor(info.BorderColor, out var cantConstrain);
|
BorderColor borderColor = GetConstrainedBorderColor(info.BorderColor, out bool cantConstrain);
|
||||||
|
|
||||||
var samplerCreateInfo = new Silk.NET.Vulkan.SamplerCreateInfo
|
Silk.NET.Vulkan.SamplerCreateInfo samplerCreateInfo = new Silk.NET.Vulkan.SamplerCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.SamplerCreateInfo,
|
SType = StructureType.SamplerCreateInfo,
|
||||||
MagFilter = info.MagFilter.Convert(),
|
MagFilter = info.MagFilter.Convert(),
|
||||||
@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (cantConstrain && gd.Capabilities.SupportsCustomBorderColor)
|
if (cantConstrain && gd.Capabilities.SupportsCustomBorderColor)
|
||||||
{
|
{
|
||||||
var color = new ClearColorValue(
|
ClearColorValue color = new ClearColorValue(
|
||||||
info.BorderColor.Red,
|
info.BorderColor.Red,
|
||||||
info.BorderColor.Green,
|
info.BorderColor.Green,
|
||||||
info.BorderColor.Blue,
|
info.BorderColor.Blue,
|
||||||
@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
samplerCreateInfo.BorderColor = BorderColor.FloatCustomExt;
|
samplerCreateInfo.BorderColor = BorderColor.FloatCustomExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
gd.Api.CreateSampler(device, in samplerCreateInfo, null, out var sampler).ThrowOnError();
|
gd.Api.CreateSampler(device, in samplerCreateInfo, null, out Sampler sampler).ThrowOnError();
|
||||||
|
|
||||||
_sampler = new Auto<DisposableSampler>(new DisposableSampler(gd.Api, device, sampler));
|
_sampler = new Auto<DisposableSampler>(new DisposableSampler(gd.Api, device, sampler));
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Result = shaderc.Result;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
@ -58,7 +59,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
fixed (byte* pCode = spirv)
|
fixed (byte* pCode = spirv)
|
||||||
{
|
{
|
||||||
var shaderModuleCreateInfo = new ShaderModuleCreateInfo
|
ShaderModuleCreateInfo shaderModuleCreateInfo = new ShaderModuleCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ShaderModuleCreateInfo,
|
SType = StructureType.ShaderModuleCreateInfo,
|
||||||
CodeSize = (uint)spirv.Length,
|
CodeSize = (uint)spirv.Length,
|
||||||
@ -87,7 +88,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
options.SetTargetEnvironment(TargetEnvironment.Vulkan, EnvironmentVersion.Vulkan_1_2);
|
options.SetTargetEnvironment(TargetEnvironment.Vulkan, EnvironmentVersion.Vulkan_1_2);
|
||||||
Compiler compiler = new(options);
|
Compiler compiler = new(options);
|
||||||
var scr = compiler.Compile(glsl, "Ryu", GetShaderCShaderStage(stage));
|
Result scr = compiler.Compile(glsl, "Ryu", GetShaderCShaderStage(stage));
|
||||||
|
|
||||||
lock (_shaderOptionsLock)
|
lock (_shaderOptionsLock)
|
||||||
{
|
{
|
||||||
@ -101,7 +102,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var spirvBytes = new Span<byte>((void*)scr.CodePointer, (int)scr.CodeLength);
|
Span<byte> spirvBytes = new Span<byte>((void*)scr.CodePointer, (int)scr.CodeLength);
|
||||||
|
|
||||||
byte[] code = new byte[(scr.CodeLength + 3) & ~3];
|
byte[] code = new byte[(scr.CodeLength + 3) & ~3];
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
gd.Shaders.Add(this);
|
gd.Shaders.Add(this);
|
||||||
|
|
||||||
var internalShaders = new Shader[shaders.Length];
|
Shader[] internalShaders = new Shader[shaders.Length];
|
||||||
|
|
||||||
_infos = new PipelineShaderStageCreateInfo[shaders.Length];
|
_infos = new PipelineShaderStageCreateInfo[shaders.Length];
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < shaders.Length; i++)
|
for (int i = 0; i < shaders.Length; i++)
|
||||||
{
|
{
|
||||||
var shader = new Shader(gd.Api, device, shaders[i]);
|
Shader shader = new Shader(gd.Api, device, shaders[i]);
|
||||||
|
|
||||||
stages |= 1u << shader.StageFlags switch
|
stages |= 1u << shader.StageFlags switch
|
||||||
{
|
{
|
||||||
@ -173,7 +173,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// Can't use any of the reserved usages.
|
// Can't use any of the reserved usages.
|
||||||
for (int i = 0; i < uniformUsage.Count; i++)
|
for (int i = 0; i < uniformUsage.Count; i++)
|
||||||
{
|
{
|
||||||
var binding = uniformUsage[i].Binding;
|
int binding = uniformUsage[i].Binding;
|
||||||
|
|
||||||
if (reserved.Contains(binding) ||
|
if (reserved.Contains(binding) ||
|
||||||
binding >= Constants.MaxPushDescriptorBinding ||
|
binding >= Constants.MaxPushDescriptorBinding ||
|
||||||
@ -203,7 +203,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// The reserved bindings were selected when determining if push descriptors could be used.
|
// The reserved bindings were selected when determining if push descriptors could be used.
|
||||||
int[] reserved = gd.GetPushDescriptorReservedBindings(false);
|
int[] reserved = gd.GetPushDescriptorReservedBindings(false);
|
||||||
|
|
||||||
var result = new ResourceDescriptorCollection[sets.Count];
|
ResourceDescriptorCollection[] result = new ResourceDescriptorCollection[sets.Count];
|
||||||
|
|
||||||
for (int i = 0; i < sets.Count; i++)
|
for (int i = 0; i < sets.Count; i++)
|
||||||
{
|
{
|
||||||
@ -212,7 +212,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
// Push descriptors apply here. Remove reserved bindings.
|
// Push descriptors apply here. Remove reserved bindings.
|
||||||
ResourceDescriptorCollection original = sets[i];
|
ResourceDescriptorCollection original = sets[i];
|
||||||
|
|
||||||
var pdUniforms = new ResourceDescriptor[original.Descriptors.Count];
|
ResourceDescriptor[] pdUniforms = new ResourceDescriptor[original.Descriptors.Count];
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|
||||||
foreach (ResourceDescriptor descriptor in original.Descriptors)
|
foreach (ResourceDescriptor descriptor in original.Descriptors)
|
||||||
@ -364,7 +364,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private DescriptorSetTemplate[] BuildTemplates(bool usePushDescriptors)
|
private DescriptorSetTemplate[] BuildTemplates(bool usePushDescriptors)
|
||||||
{
|
{
|
||||||
var templates = new DescriptorSetTemplate[BindingSegments.Length];
|
DescriptorSetTemplate[] templates = new DescriptorSetTemplate[BindingSegments.Length];
|
||||||
|
|
||||||
for (int setIndex = 0; setIndex < BindingSegments.Length; setIndex++)
|
for (int setIndex = 0; setIndex < BindingSegments.Length; setIndex++)
|
||||||
{
|
{
|
||||||
@ -433,9 +433,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PipelineStageFlags buffer = PipelineStageFlags.None;
|
PipelineStageFlags buffer = PipelineStageFlags.None;
|
||||||
PipelineStageFlags texture = PipelineStageFlags.None;
|
PipelineStageFlags texture = PipelineStageFlags.None;
|
||||||
|
|
||||||
foreach (var set in setUsages)
|
foreach (ResourceUsageCollection set in setUsages)
|
||||||
{
|
{
|
||||||
foreach (var range in set.Usages)
|
foreach (ResourceUsage range in set.Usages)
|
||||||
{
|
{
|
||||||
if (range.Write)
|
if (range.Write)
|
||||||
{
|
{
|
||||||
@ -498,7 +498,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < _shaders.Length; i++)
|
for (int i = 0; i < _shaders.Length; i++)
|
||||||
{
|
{
|
||||||
var shader = _shaders[i];
|
Shader shader = _shaders[i];
|
||||||
|
|
||||||
if (shader.CompileStatus != ProgramLinkStatus.Success)
|
if (shader.CompileStatus != ProgramLinkStatus.Success)
|
||||||
{
|
{
|
||||||
@ -557,12 +557,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
// First, we need to create a render pass object compatible with the one that will be used at runtime.
|
// First, we need to create a render pass object compatible with the one that will be used at runtime.
|
||||||
// The active attachment formats have been provided by the abstraction layer.
|
// The active attachment formats have been provided by the abstraction layer.
|
||||||
var renderPass = CreateDummyRenderPass();
|
DisposableRenderPass renderPass = CreateDummyRenderPass();
|
||||||
|
|
||||||
PipelineState pipeline = _state.ToVulkanPipelineState(_gd);
|
PipelineState pipeline = _state.ToVulkanPipelineState(_gd);
|
||||||
|
|
||||||
// Copy the shader stage info to the pipeline.
|
// Copy the shader stage info to the pipeline.
|
||||||
var stages = pipeline.Stages.AsSpan();
|
Span<PipelineShaderStageCreateInfo> stages = pipeline.Stages.AsSpan();
|
||||||
|
|
||||||
for (int i = 0; i < _shaders.Length; i++)
|
for (int i = 0; i < _shaders.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < Map.Length; ++i)
|
for (int i = 0; i < Map.Length; ++i)
|
||||||
{
|
{
|
||||||
var typeSize = SizeOf(description[i].Type);
|
uint typeSize = SizeOf(description[i].Type);
|
||||||
Map[i] = new SpecializationMapEntry(description[i].Id, structSize, typeSize);
|
Map[i] = new SpecializationMapEntry(description[i].Id, structSize, typeSize);
|
||||||
structSize += typeSize;
|
structSize += typeSize;
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_data = new byte[data.Length];
|
_data = new byte[data.Length];
|
||||||
data.CopyTo(_data);
|
data.CopyTo(_data);
|
||||||
|
|
||||||
var hc = new HashCode();
|
HashCode hc = new HashCode();
|
||||||
hc.AddBytes(data);
|
hc.AddBytes(data);
|
||||||
_hash = hc.ToHashCode();
|
_hash = hc.ToHashCode();
|
||||||
}
|
}
|
||||||
|
@ -107,8 +107,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void PushDataImpl(CommandBufferScoped cbs, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
private void PushDataImpl(CommandBufferScoped cbs, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
var srcBuffer = _buffer.GetBuffer();
|
Auto<DisposableBuffer> srcBuffer = _buffer.GetBuffer();
|
||||||
var dstBuffer = dst.GetBuffer(cbs.CommandBuffer, dstOffset, data.Length, true);
|
Auto<DisposableBuffer> dstBuffer = dst.GetBuffer(cbs.CommandBuffer, dstOffset, data.Length, true);
|
||||||
|
|
||||||
int offset = _freeOffset;
|
int offset = _freeOffset;
|
||||||
int capacity = BufferSize - offset;
|
int capacity = BufferSize - offset;
|
||||||
@ -242,7 +242,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private bool WaitFreeCompleted(CommandBufferPool cbp)
|
private bool WaitFreeCompleted(CommandBufferPool cbp)
|
||||||
{
|
{
|
||||||
if (_pendingCopies.TryPeek(out var pc))
|
if (_pendingCopies.TryPeek(out PendingCopy pc))
|
||||||
{
|
{
|
||||||
if (!pc.Fence.IsSignaled())
|
if (!pc.Fence.IsSignaled())
|
||||||
{
|
{
|
||||||
@ -254,7 +254,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
pc.Fence.Wait();
|
pc.Fence.Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
var dequeued = _pendingCopies.Dequeue();
|
PendingCopy dequeued = _pendingCopies.Dequeue();
|
||||||
Debug.Assert(dequeued.Fence == pc.Fence);
|
Debug.Assert(dequeued.Fence == pc.Fence);
|
||||||
_freeSize += pc.Size;
|
_freeSize += pc.Size;
|
||||||
pc.Fence.Put();
|
pc.Fence.Put();
|
||||||
@ -266,10 +266,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public void FreeCompleted()
|
public void FreeCompleted()
|
||||||
{
|
{
|
||||||
FenceHolder signalledFence = null;
|
FenceHolder signalledFence = null;
|
||||||
while (_pendingCopies.TryPeek(out var pc) && (pc.Fence == signalledFence || pc.Fence.IsSignaled()))
|
while (_pendingCopies.TryPeek(out PendingCopy pc) && (pc.Fence == signalledFence || pc.Fence.IsSignaled()))
|
||||||
{
|
{
|
||||||
signalledFence = pc.Fence; // Already checked - don't need to do it again.
|
signalledFence = pc.Fence; // Already checked - don't need to do it again.
|
||||||
var dequeued = _pendingCopies.Dequeue();
|
PendingCopy dequeued = _pendingCopies.Dequeue();
|
||||||
Debug.Assert(dequeued.Fence == pc.Fence);
|
Debug.Assert(dequeued.Fence == pc.Fence);
|
||||||
_freeSize += pc.Size;
|
_freeSize += pc.Size;
|
||||||
pc.Fence.Put();
|
pc.Fence.Put();
|
||||||
@ -282,7 +282,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
_gd.BufferManager.Delete(Handle);
|
_gd.BufferManager.Delete(Handle);
|
||||||
|
|
||||||
while (_pendingCopies.TryDequeue(out var pc))
|
while (_pendingCopies.TryDequeue(out PendingCopy pc))
|
||||||
{
|
{
|
||||||
pc.Fence.Put();
|
pc.Fence.Put();
|
||||||
}
|
}
|
||||||
|
@ -148,8 +148,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < textures.Length; i++)
|
for (int i = 0; i < textures.Length; i++)
|
||||||
{
|
{
|
||||||
ref var texture = ref textures[i];
|
ref DescriptorImageInfo texture = ref textures[i];
|
||||||
ref var refs = ref _textureRefs[i];
|
ref TextureRef refs = ref _textureRefs[i];
|
||||||
|
|
||||||
if (i > 0 && _textureRefs[i - 1].View == refs.View && _textureRefs[i - 1].Sampler == refs.Sampler)
|
if (i > 0 && _textureRefs[i - 1].View == refs.View && _textureRefs[i - 1].Sampler == refs.Sampler)
|
||||||
{
|
{
|
||||||
|
@ -34,8 +34,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return Math.Clamp(value, 0, max);
|
return Math.Clamp(value, 0, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
var xy1 = new Offset3D(Clamp(extents.X1, width) >> level, Clamp(extents.Y1, height) >> level, 0);
|
Offset3D xy1 = new Offset3D(Clamp(extents.X1, width) >> level, Clamp(extents.Y1, height) >> level, 0);
|
||||||
var xy2 = new Offset3D(Clamp(extents.X2, width) >> level, Clamp(extents.Y2, height) >> level, 1);
|
Offset3D xy2 = new Offset3D(Clamp(extents.X2, width) >> level, Clamp(extents.Y2, height) >> level, 1);
|
||||||
|
|
||||||
return (xy1, xy2);
|
return (xy1, xy2);
|
||||||
}
|
}
|
||||||
@ -50,10 +50,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
dstAspectFlags = dstInfo.Format.ConvertAspectFlags();
|
dstAspectFlags = dstInfo.Format.ConvertAspectFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
var srcOffsets = new ImageBlit.SrcOffsetsBuffer();
|
ImageBlit.SrcOffsetsBuffer srcOffsets = new ImageBlit.SrcOffsetsBuffer();
|
||||||
var dstOffsets = new ImageBlit.DstOffsetsBuffer();
|
ImageBlit.DstOffsetsBuffer dstOffsets = new ImageBlit.DstOffsetsBuffer();
|
||||||
|
|
||||||
var filter = linearFilter && !dstInfo.Format.IsDepthOrStencil() ? Filter.Linear : Filter.Nearest;
|
Filter filter = linearFilter && !dstInfo.Format.IsDepthOrStencil() ? Filter.Linear : Filter.Nearest;
|
||||||
|
|
||||||
TextureView.InsertImageBarrier(
|
TextureView.InsertImageBarrier(
|
||||||
api,
|
api,
|
||||||
@ -74,13 +74,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int level = 0; level < levels; level++)
|
for (int level = 0; level < levels; level++)
|
||||||
{
|
{
|
||||||
var srcSl = new ImageSubresourceLayers(srcAspectFlags, copySrcLevel, (uint)srcLayer, (uint)layers);
|
ImageSubresourceLayers srcSl = new ImageSubresourceLayers(srcAspectFlags, copySrcLevel, (uint)srcLayer, (uint)layers);
|
||||||
var dstSl = new ImageSubresourceLayers(dstAspectFlags, copyDstLevel, (uint)dstLayer, (uint)layers);
|
ImageSubresourceLayers dstSl = new ImageSubresourceLayers(dstAspectFlags, copyDstLevel, (uint)dstLayer, (uint)layers);
|
||||||
|
|
||||||
(srcOffsets.Element0, srcOffsets.Element1) = ExtentsToOffset3D(srcRegion, srcInfo.Width, srcInfo.Height, level);
|
(srcOffsets.Element0, srcOffsets.Element1) = ExtentsToOffset3D(srcRegion, srcInfo.Width, srcInfo.Height, level);
|
||||||
(dstOffsets.Element0, dstOffsets.Element1) = ExtentsToOffset3D(dstRegion, dstInfo.Width, dstInfo.Height, level);
|
(dstOffsets.Element0, dstOffsets.Element1) = ExtentsToOffset3D(dstRegion, dstInfo.Width, dstInfo.Height, level);
|
||||||
|
|
||||||
var region = new ImageBlit
|
ImageBlit region = new ImageBlit
|
||||||
{
|
{
|
||||||
SrcSubresource = srcSl,
|
SrcSubresource = srcSl,
|
||||||
SrcOffsets = srcOffsets,
|
SrcOffsets = srcOffsets,
|
||||||
@ -299,13 +299,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var srcSl = new ImageSubresourceLayers(
|
ImageSubresourceLayers srcSl = new ImageSubresourceLayers(
|
||||||
srcAspect,
|
srcAspect,
|
||||||
(uint)(srcViewLevel + srcLevel + level),
|
(uint)(srcViewLevel + srcLevel + level),
|
||||||
(uint)(srcViewLayer + srcLayer),
|
(uint)(srcViewLayer + srcLayer),
|
||||||
(uint)srcLayers);
|
(uint)srcLayers);
|
||||||
|
|
||||||
var dstSl = new ImageSubresourceLayers(
|
ImageSubresourceLayers dstSl = new ImageSubresourceLayers(
|
||||||
dstAspect,
|
dstAspect,
|
||||||
(uint)(dstViewLevel + dstLevel + level),
|
(uint)(dstViewLevel + dstLevel + level),
|
||||||
(uint)(dstViewLayer + dstLayer),
|
(uint)(dstViewLayer + dstLayer),
|
||||||
@ -314,17 +314,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width;
|
int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width;
|
||||||
int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height;
|
int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height;
|
||||||
|
|
||||||
var extent = new Extent3D((uint)copyWidth, (uint)copyHeight, (uint)srcDepth);
|
Extent3D extent = new Extent3D((uint)copyWidth, (uint)copyHeight, (uint)srcDepth);
|
||||||
|
|
||||||
if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples)
|
if (srcInfo.Samples > 1 && srcInfo.Samples != dstInfo.Samples)
|
||||||
{
|
{
|
||||||
var region = new ImageResolve(srcSl, new Offset3D(0, 0, srcZ), dstSl, new Offset3D(0, 0, dstZ), extent);
|
ImageResolve region = new ImageResolve(srcSl, new Offset3D(0, 0, srcZ), dstSl, new Offset3D(0, 0, dstZ), extent);
|
||||||
|
|
||||||
api.CmdResolveImage(commandBuffer, srcImage, ImageLayout.General, dstImage, ImageLayout.General, 1, in region);
|
api.CmdResolveImage(commandBuffer, srcImage, ImageLayout.General, dstImage, ImageLayout.General, 1, in region);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var region = new ImageCopy(srcSl, new Offset3D(0, 0, srcZ), dstSl, new Offset3D(0, 0, dstZ), extent);
|
ImageCopy region = new ImageCopy(srcSl, new Offset3D(0, 0, srcZ), dstSl, new Offset3D(0, 0, dstZ), extent);
|
||||||
|
|
||||||
api.CmdCopyImage(commandBuffer, srcImage, ImageLayout.General, dstImage, ImageLayout.General, 1, in region);
|
api.CmdCopyImage(commandBuffer, srcImage, ImageLayout.General, dstImage, ImageLayout.General, 1, in region);
|
||||||
}
|
}
|
||||||
@ -360,10 +360,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
TextureView src,
|
TextureView src,
|
||||||
TextureView dst)
|
TextureView dst)
|
||||||
{
|
{
|
||||||
var dsAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 0, ImageLayout.General);
|
AttachmentReference2 dsAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 0, ImageLayout.General);
|
||||||
var dsResolveAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 1, ImageLayout.General);
|
AttachmentReference2 dsResolveAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 1, ImageLayout.General);
|
||||||
|
|
||||||
var subpassDsResolve = new SubpassDescriptionDepthStencilResolve
|
SubpassDescriptionDepthStencilResolve subpassDsResolve = new SubpassDescriptionDepthStencilResolve
|
||||||
{
|
{
|
||||||
SType = StructureType.SubpassDescriptionDepthStencilResolve,
|
SType = StructureType.SubpassDescriptionDepthStencilResolve,
|
||||||
PDepthStencilResolveAttachment = &dsResolveAttachmentReference,
|
PDepthStencilResolveAttachment = &dsResolveAttachmentReference,
|
||||||
@ -371,7 +371,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
StencilResolveMode = ResolveModeFlags.SampleZeroBit,
|
StencilResolveMode = ResolveModeFlags.SampleZeroBit,
|
||||||
};
|
};
|
||||||
|
|
||||||
var subpass = new SubpassDescription2
|
SubpassDescription2 subpass = new SubpassDescription2
|
||||||
{
|
{
|
||||||
SType = StructureType.SubpassDescription2,
|
SType = StructureType.SubpassDescription2,
|
||||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||||
@ -407,11 +407,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ImageLayout.General,
|
ImageLayout.General,
|
||||||
ImageLayout.General);
|
ImageLayout.General);
|
||||||
|
|
||||||
var subpassDependency = PipelineConverter.CreateSubpassDependency2(gd);
|
SubpassDependency2 subpassDependency = PipelineConverter.CreateSubpassDependency2(gd);
|
||||||
|
|
||||||
fixed (AttachmentDescription2* pAttachmentDescs = attachmentDescs)
|
fixed (AttachmentDescription2* pAttachmentDescs = attachmentDescs)
|
||||||
{
|
{
|
||||||
var renderPassCreateInfo = new RenderPassCreateInfo2
|
RenderPassCreateInfo2 renderPassCreateInfo = new RenderPassCreateInfo2
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassCreateInfo2,
|
SType = StructureType.RenderPassCreateInfo2,
|
||||||
PAttachments = pAttachmentDescs,
|
PAttachments = pAttachmentDescs,
|
||||||
@ -422,19 +422,19 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
DependencyCount = 1,
|
DependencyCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateRenderPass2(device, in renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
gd.Api.CreateRenderPass2(device, in renderPassCreateInfo, null, out RenderPass renderPass).ThrowOnError();
|
||||||
|
|
||||||
using var rp = new Auto<DisposableRenderPass>(new DisposableRenderPass(gd.Api, device, renderPass));
|
using Auto<DisposableRenderPass> rp = new Auto<DisposableRenderPass>(new DisposableRenderPass(gd.Api, device, renderPass));
|
||||||
|
|
||||||
ImageView* attachments = stackalloc ImageView[2];
|
ImageView* attachments = stackalloc ImageView[2];
|
||||||
|
|
||||||
var srcView = src.GetImageViewForAttachment();
|
Auto<DisposableImageView> srcView = src.GetImageViewForAttachment();
|
||||||
var dstView = dst.GetImageViewForAttachment();
|
Auto<DisposableImageView> dstView = dst.GetImageViewForAttachment();
|
||||||
|
|
||||||
attachments[0] = srcView.Get(cbs).Value;
|
attachments[0] = srcView.Get(cbs).Value;
|
||||||
attachments[1] = dstView.Get(cbs).Value;
|
attachments[1] = dstView.Get(cbs).Value;
|
||||||
|
|
||||||
var framebufferCreateInfo = new FramebufferCreateInfo
|
FramebufferCreateInfo framebufferCreateInfo = new FramebufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.FramebufferCreateInfo,
|
SType = StructureType.FramebufferCreateInfo,
|
||||||
RenderPass = rp.Get(cbs).Value,
|
RenderPass = rp.Get(cbs).Value,
|
||||||
@ -445,13 +445,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Layers = (uint)src.Layers,
|
Layers = (uint)src.Layers,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateFramebuffer(device, in framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
gd.Api.CreateFramebuffer(device, in framebufferCreateInfo, null, out Framebuffer framebuffer).ThrowOnError();
|
||||||
using var fb = new Auto<DisposableFramebuffer>(new DisposableFramebuffer(gd.Api, device, framebuffer), null, srcView, dstView);
|
using Auto<DisposableFramebuffer> fb = new Auto<DisposableFramebuffer>(new DisposableFramebuffer(gd.Api, device, framebuffer), null, srcView, dstView);
|
||||||
|
|
||||||
var renderArea = new Rect2D(null, new Extent2D((uint)src.Info.Width, (uint)src.Info.Height));
|
Rect2D renderArea = new Rect2D(null, new Extent2D((uint)src.Info.Width, (uint)src.Info.Height));
|
||||||
var clearValue = new ClearValue();
|
ClearValue clearValue = new ClearValue();
|
||||||
|
|
||||||
var renderPassBeginInfo = new RenderPassBeginInfo
|
RenderPassBeginInfo renderPassBeginInfo = new RenderPassBeginInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassBeginInfo,
|
SType = StructureType.RenderPassBeginInfo,
|
||||||
RenderPass = rp.Get(cbs).Value,
|
RenderPass = rp.Get(cbs).Value,
|
||||||
|
@ -79,23 +79,23 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample();
|
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample();
|
||||||
|
|
||||||
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
|
VkFormat format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
|
||||||
var levels = (uint)info.Levels;
|
uint levels = (uint)info.Levels;
|
||||||
var layers = (uint)info.GetLayers();
|
uint layers = (uint)info.GetLayers();
|
||||||
var depth = (uint)(info.Target == Target.Texture3D ? info.Depth : 1);
|
uint depth = (uint)(info.Target == Target.Texture3D ? info.Depth : 1);
|
||||||
|
|
||||||
VkFormat = format;
|
VkFormat = format;
|
||||||
_depthOrLayers = info.GetDepthOrLayers();
|
_depthOrLayers = info.GetDepthOrLayers();
|
||||||
|
|
||||||
var type = info.Target.Convert();
|
ImageType type = info.Target.Convert();
|
||||||
|
|
||||||
var extent = new Extent3D((uint)info.Width, (uint)info.Height, depth);
|
Extent3D extent = new Extent3D((uint)info.Width, (uint)info.Height, depth);
|
||||||
|
|
||||||
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
|
SampleCountFlags sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
|
||||||
|
|
||||||
var usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, true);
|
ImageUsageFlags usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, true);
|
||||||
|
|
||||||
var flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
|
ImageCreateFlags flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
|
||||||
|
|
||||||
// This flag causes mipmapped texture arrays to break on AMD GCN, so for that copy dependencies are forced for aliasing as cube.
|
// This flag causes mipmapped texture arrays to break on AMD GCN, so for that copy dependencies are forced for aliasing as cube.
|
||||||
bool isCube = info.Target == Target.Cubemap || info.Target == Target.CubemapArray;
|
bool isCube = info.Target == Target.Cubemap || info.Target == Target.CubemapArray;
|
||||||
@ -111,7 +111,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
flags |= ImageCreateFlags.Create2DArrayCompatibleBit;
|
flags |= ImageCreateFlags.Create2DArrayCompatibleBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageCreateInfo = new ImageCreateInfo
|
ImageCreateInfo imageCreateInfo = new ImageCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageCreateInfo,
|
SType = StructureType.ImageCreateInfo,
|
||||||
ImageType = type,
|
ImageType = type,
|
||||||
@ -131,8 +131,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (foreignAllocation == null)
|
if (foreignAllocation == null)
|
||||||
{
|
{
|
||||||
gd.Api.GetImageMemoryRequirements(device, _image, out var requirements);
|
gd.Api.GetImageMemoryRequirements(device, _image, out MemoryRequirements requirements);
|
||||||
var allocation = gd.MemoryAllocator.AllocateDeviceMemory(requirements, DefaultImageMemoryFlags);
|
MemoryAllocation allocation = gd.MemoryAllocator.AllocateDeviceMemory(requirements, DefaultImageMemoryFlags);
|
||||||
|
|
||||||
if (allocation.Memory.Handle == 0UL)
|
if (allocation.Memory.Handle == 0UL)
|
||||||
{
|
{
|
||||||
@ -153,7 +153,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
_foreignAllocationAuto = foreignAllocation;
|
_foreignAllocationAuto = foreignAllocation;
|
||||||
foreignAllocation.IncrementReferenceCount();
|
foreignAllocation.IncrementReferenceCount();
|
||||||
var allocation = foreignAllocation.GetUnsafe();
|
MemoryAllocation allocation = foreignAllocation.GetUnsafe();
|
||||||
|
|
||||||
gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError();
|
gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError();
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public TextureStorage CreateAliasedColorForDepthStorageUnsafe(Format format)
|
public TextureStorage CreateAliasedColorForDepthStorageUnsafe(Format format)
|
||||||
{
|
{
|
||||||
var colorFormat = format switch
|
Format colorFormat = format switch
|
||||||
{
|
{
|
||||||
Format.S8Uint => Format.R8Unorm,
|
Format.S8Uint => Format.R8Unorm,
|
||||||
Format.D16Unorm => Format.R16Unorm,
|
Format.D16Unorm => Format.R16Unorm,
|
||||||
@ -182,11 +182,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public TextureStorage CreateAliasedStorageUnsafe(Format format)
|
public TextureStorage CreateAliasedStorageUnsafe(Format format)
|
||||||
{
|
{
|
||||||
if (_aliasedStorages == null || !_aliasedStorages.TryGetValue(format, out var storage))
|
if (_aliasedStorages == null || !_aliasedStorages.TryGetValue(format, out TextureStorage storage))
|
||||||
{
|
{
|
||||||
_aliasedStorages ??= new Dictionary<Format, TextureStorage>();
|
_aliasedStorages ??= new Dictionary<Format, TextureStorage>();
|
||||||
|
|
||||||
var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel);
|
TextureCreateInfo info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel);
|
||||||
|
|
||||||
storage = new TextureStorage(_gd, _device, info, _allocationAuto);
|
storage = new TextureStorage(_gd, _device, info, _allocationAuto);
|
||||||
|
|
||||||
@ -272,11 +272,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var aspectFlags = _info.Format.ConvertAspectFlags();
|
ImageAspectFlags aspectFlags = _info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, (uint)_info.Levels, 0, (uint)_info.GetLayers());
|
ImageSubresourceRange subresourceRange = new ImageSubresourceRange(aspectFlags, 0, (uint)_info.Levels, 0, (uint)_info.GetLayers());
|
||||||
|
|
||||||
var barrier = new ImageMemoryBarrier
|
ImageMemoryBarrier barrier = new ImageMemoryBarrier
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageMemoryBarrier,
|
SType = StructureType.ImageMemoryBarrier,
|
||||||
SrcAccessMask = 0,
|
SrcAccessMask = 0,
|
||||||
@ -309,7 +309,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported, bool extendedUsage)
|
public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported, bool extendedUsage)
|
||||||
{
|
{
|
||||||
var usage = DefaultUsageFlags;
|
ImageUsageFlags usage = DefaultUsageFlags;
|
||||||
|
|
||||||
if (format.IsDepthOrStencil())
|
if (format.IsDepthOrStencil())
|
||||||
{
|
{
|
||||||
@ -402,17 +402,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
int rowLength = (Info.GetMipStride(level) / Info.BytesPerPixel) * Info.BlockWidth;
|
int rowLength = (Info.GetMipStride(level) / Info.BytesPerPixel) * Info.BlockWidth;
|
||||||
|
|
||||||
var sl = new ImageSubresourceLayers(
|
ImageSubresourceLayers sl = new ImageSubresourceLayers(
|
||||||
aspectFlags,
|
aspectFlags,
|
||||||
(uint)(dstLevel + level),
|
(uint)(dstLevel + level),
|
||||||
(uint)layer,
|
(uint)layer,
|
||||||
(uint)layers);
|
(uint)layers);
|
||||||
|
|
||||||
var extent = new Extent3D((uint)width, (uint)height, (uint)depth);
|
Extent3D extent = new Extent3D((uint)width, (uint)height, (uint)depth);
|
||||||
|
|
||||||
int z = is3D ? dstLayer : 0;
|
int z = is3D ? dstLayer : 0;
|
||||||
|
|
||||||
var region = new BufferImageCopy(
|
BufferImageCopy region = new BufferImageCopy(
|
||||||
(ulong)offset,
|
(ulong)offset,
|
||||||
(uint)BitUtils.AlignUp(rowLength, Info.BlockWidth),
|
(uint)BitUtils.AlignUp(rowLength, Info.BlockWidth),
|
||||||
(uint)BitUtils.AlignUp(height, Info.BlockHeight),
|
(uint)BitUtils.AlignUp(height, Info.BlockHeight),
|
||||||
@ -601,7 +601,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (_aliasedStorages != null)
|
if (_aliasedStorages != null)
|
||||||
{
|
{
|
||||||
foreach (var storage in _aliasedStorages.Values)
|
foreach (TextureStorage storage in _aliasedStorages.Values)
|
||||||
{
|
{
|
||||||
storage.Dispose();
|
storage.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -63,20 +63,20 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample();
|
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample();
|
||||||
|
|
||||||
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
|
VkFormat format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
|
||||||
var usage = TextureStorage.GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, false);
|
ImageUsageFlags usage = TextureStorage.GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, false);
|
||||||
|
|
||||||
var levels = (uint)info.Levels;
|
uint levels = (uint)info.Levels;
|
||||||
var layers = (uint)info.GetLayers();
|
uint layers = (uint)info.GetLayers();
|
||||||
|
|
||||||
VkFormat = format;
|
VkFormat = format;
|
||||||
|
|
||||||
var type = info.Target.ConvertView();
|
ImageViewType type = info.Target.ConvertView();
|
||||||
|
|
||||||
var swizzleR = info.SwizzleR.Convert();
|
ComponentSwizzle swizzleR = info.SwizzleR.Convert();
|
||||||
var swizzleG = info.SwizzleG.Convert();
|
ComponentSwizzle swizzleG = info.SwizzleG.Convert();
|
||||||
var swizzleB = info.SwizzleB.Convert();
|
ComponentSwizzle swizzleB = info.SwizzleB.Convert();
|
||||||
var swizzleA = info.SwizzleA.Convert();
|
ComponentSwizzle swizzleA = info.SwizzleA.Convert();
|
||||||
|
|
||||||
if (info.Format == Format.R5G5B5A1Unorm ||
|
if (info.Format == Format.R5G5B5A1Unorm ||
|
||||||
info.Format == Format.R5G5B5X1Unorm ||
|
info.Format == Format.R5G5B5X1Unorm ||
|
||||||
@ -86,8 +86,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
else if (VkFormat == VkFormat.R4G4B4A4UnormPack16 || info.Format == Format.A1B5G5R5Unorm)
|
else if (VkFormat == VkFormat.R4G4B4A4UnormPack16 || info.Format == Format.A1B5G5R5Unorm)
|
||||||
{
|
{
|
||||||
var tempB = swizzleB;
|
ComponentSwizzle tempB = swizzleB;
|
||||||
var tempA = swizzleA;
|
ComponentSwizzle tempA = swizzleA;
|
||||||
|
|
||||||
swizzleB = swizzleG;
|
swizzleB = swizzleG;
|
||||||
swizzleA = swizzleR;
|
swizzleA = swizzleR;
|
||||||
@ -95,23 +95,23 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
swizzleG = tempB;
|
swizzleG = tempB;
|
||||||
}
|
}
|
||||||
|
|
||||||
var componentMapping = new ComponentMapping(swizzleR, swizzleG, swizzleB, swizzleA);
|
ComponentMapping componentMapping = new ComponentMapping(swizzleR, swizzleG, swizzleB, swizzleA);
|
||||||
|
|
||||||
var aspectFlags = info.Format.ConvertAspectFlags(info.DepthStencilMode);
|
ImageAspectFlags aspectFlags = info.Format.ConvertAspectFlags(info.DepthStencilMode);
|
||||||
var aspectFlagsDepth = info.Format.ConvertAspectFlags();
|
ImageAspectFlags aspectFlagsDepth = info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
var subresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, layers);
|
ImageSubresourceRange subresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, layers);
|
||||||
var subresourceRangeDepth = new ImageSubresourceRange(aspectFlagsDepth, (uint)firstLevel, levels, (uint)firstLayer, layers);
|
ImageSubresourceRange subresourceRangeDepth = new ImageSubresourceRange(aspectFlagsDepth, (uint)firstLevel, levels, (uint)firstLayer, layers);
|
||||||
|
|
||||||
unsafe Auto<DisposableImageView> CreateImageView(ComponentMapping cm, ImageSubresourceRange sr, ImageViewType viewType, ImageUsageFlags usageFlags)
|
unsafe Auto<DisposableImageView> CreateImageView(ComponentMapping cm, ImageSubresourceRange sr, ImageViewType viewType, ImageUsageFlags usageFlags)
|
||||||
{
|
{
|
||||||
var imageViewUsage = new ImageViewUsageCreateInfo
|
ImageViewUsageCreateInfo imageViewUsage = new ImageViewUsageCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageViewUsageCreateInfo,
|
SType = StructureType.ImageViewUsageCreateInfo,
|
||||||
Usage = usageFlags,
|
Usage = usageFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
var imageCreateInfo = new ImageViewCreateInfo
|
ImageViewCreateInfo imageCreateInfo = new ImageViewCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageViewCreateInfo,
|
SType = StructureType.ImageViewCreateInfo,
|
||||||
Image = storage.GetImageForViewCreation(),
|
Image = storage.GetImageForViewCreation(),
|
||||||
@ -122,7 +122,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PNext = &imageViewUsage,
|
PNext = &imageViewUsage,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateImageView(device, in imageCreateInfo, null, out var imageView).ThrowOnError();
|
gd.Api.CreateImageView(device, in imageCreateInfo, null, out ImageView imageView).ThrowOnError();
|
||||||
return new Auto<DisposableImageView>(new DisposableImageView(gd.Api, device, imageView), null, storage.GetImage());
|
return new Auto<DisposableImageView>(new DisposableImageView(gd.Api, device, imageView), null, storage.GetImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +136,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_imageView = CreateImageView(componentMapping, subresourceRange, type, shaderUsage);
|
_imageView = CreateImageView(componentMapping, subresourceRange, type, shaderUsage);
|
||||||
|
|
||||||
// Framebuffer attachments and storage images requires a identity component mapping.
|
// Framebuffer attachments and storage images requires a identity component mapping.
|
||||||
var identityComponentMapping = new ComponentMapping(
|
ComponentMapping identityComponentMapping = new ComponentMapping(
|
||||||
ComponentSwizzle.R,
|
ComponentSwizzle.R,
|
||||||
ComponentSwizzle.G,
|
ComponentSwizzle.G,
|
||||||
ComponentSwizzle.B,
|
ComponentSwizzle.B,
|
||||||
@ -210,8 +210,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
||||||
{
|
{
|
||||||
var src = this;
|
TextureView src = this;
|
||||||
var dst = (TextureView)destination;
|
TextureView dst = (TextureView)destination;
|
||||||
|
|
||||||
if (!Valid || !dst.Valid)
|
if (!Valid || !dst.Valid)
|
||||||
{
|
{
|
||||||
@ -220,10 +220,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_gd.PipelineInternal.EndRenderPass();
|
_gd.PipelineInternal.EndRenderPass();
|
||||||
|
|
||||||
var cbs = _gd.PipelineInternal.CurrentCommandBuffer;
|
CommandBufferScoped cbs = _gd.PipelineInternal.CurrentCommandBuffer;
|
||||||
|
|
||||||
var srcImage = src.GetImage().Get(cbs).Value;
|
Image srcImage = src.GetImage().Get(cbs).Value;
|
||||||
var dstImage = dst.GetImage().Get(cbs).Value;
|
Image dstImage = dst.GetImage().Get(cbs).Value;
|
||||||
|
|
||||||
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
|
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
|
||||||
{
|
{
|
||||||
@ -270,8 +270,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel)
|
public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel)
|
||||||
{
|
{
|
||||||
var src = this;
|
TextureView src = this;
|
||||||
var dst = (TextureView)destination;
|
TextureView dst = (TextureView)destination;
|
||||||
|
|
||||||
if (!Valid || !dst.Valid)
|
if (!Valid || !dst.Valid)
|
||||||
{
|
{
|
||||||
@ -280,10 +280,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_gd.PipelineInternal.EndRenderPass();
|
_gd.PipelineInternal.EndRenderPass();
|
||||||
|
|
||||||
var cbs = _gd.PipelineInternal.CurrentCommandBuffer;
|
CommandBufferScoped cbs = _gd.PipelineInternal.CurrentCommandBuffer;
|
||||||
|
|
||||||
var srcImage = src.GetImage().Get(cbs).Value;
|
Image srcImage = src.GetImage().Get(cbs).Value;
|
||||||
var dstImage = dst.GetImage().Get(cbs).Value;
|
Image dstImage = dst.GetImage().Get(cbs).Value;
|
||||||
|
|
||||||
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
|
if (!dst.Info.Target.IsMultisample() && Info.Target.IsMultisample())
|
||||||
{
|
{
|
||||||
@ -325,21 +325,21 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
||||||
{
|
{
|
||||||
var dst = (TextureView)destination;
|
TextureView dst = (TextureView)destination;
|
||||||
|
|
||||||
if (_gd.CommandBufferPool.OwnedByCurrentThread)
|
if (_gd.CommandBufferPool.OwnedByCurrentThread)
|
||||||
{
|
{
|
||||||
_gd.PipelineInternal.EndRenderPass();
|
_gd.PipelineInternal.EndRenderPass();
|
||||||
|
|
||||||
var cbs = _gd.PipelineInternal.CurrentCommandBuffer;
|
CommandBufferScoped cbs = _gd.PipelineInternal.CurrentCommandBuffer;
|
||||||
|
|
||||||
CopyToImpl(cbs, dst, srcRegion, dstRegion, linearFilter);
|
CopyToImpl(cbs, dst, srcRegion, dstRegion, linearFilter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var cbp = _gd.BackgroundResources.Get().GetPool();
|
CommandBufferPool cbp = _gd.BackgroundResources.Get().GetPool();
|
||||||
|
|
||||||
using var cbs = cbp.Rent();
|
using CommandBufferScoped cbs = cbp.Rent();
|
||||||
|
|
||||||
CopyToImpl(cbs, dst, srcRegion, dstRegion, linearFilter);
|
CopyToImpl(cbs, dst, srcRegion, dstRegion, linearFilter);
|
||||||
}
|
}
|
||||||
@ -347,10 +347,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void CopyToImpl(CommandBufferScoped cbs, TextureView dst, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
private void CopyToImpl(CommandBufferScoped cbs, TextureView dst, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
||||||
{
|
{
|
||||||
var src = this;
|
TextureView src = this;
|
||||||
|
|
||||||
var srcFormat = GetCompatibleGalFormat(src.Info.Format);
|
Format srcFormat = GetCompatibleGalFormat(src.Info.Format);
|
||||||
var dstFormat = GetCompatibleGalFormat(dst.Info.Format);
|
Format dstFormat = GetCompatibleGalFormat(dst.Info.Format);
|
||||||
|
|
||||||
bool srcUsesStorageFormat = src.VkFormat == src.Storage.VkFormat;
|
bool srcUsesStorageFormat = src.VkFormat == src.Storage.VkFormat;
|
||||||
bool dstUsesStorageFormat = dst.VkFormat == dst.Storage.VkFormat;
|
bool dstUsesStorageFormat = dst.VkFormat == dst.Storage.VkFormat;
|
||||||
@ -572,7 +572,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_selfManagedViews != null && _selfManagedViews.TryGetValue(format, out var view))
|
if (_selfManagedViews != null && _selfManagedViews.TryGetValue(format, out TextureView view))
|
||||||
{
|
{
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@ -612,12 +612,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public byte[] GetData(int x, int y, int width, int height)
|
public byte[] GetData(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
int size = width * height * Info.BytesPerPixel;
|
int size = width * height * Info.BytesPerPixel;
|
||||||
using var bufferHolder = _gd.BufferManager.Create(_gd, size);
|
using BufferHolder bufferHolder = _gd.BufferManager.Create(_gd, size);
|
||||||
|
|
||||||
using (var cbs = _gd.CommandBufferPool.Rent())
|
using (CommandBufferScoped cbs = _gd.CommandBufferPool.Rent())
|
||||||
{
|
{
|
||||||
var buffer = bufferHolder.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
VkBuffer buffer = bufferHolder.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
||||||
var image = GetImage().Get(cbs).Value;
|
Image image = GetImage().Get(cbs).Value;
|
||||||
|
|
||||||
CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, 0, 0, x, y, width, height);
|
CopyFromOrToBuffer(cbs.CommandBuffer, buffer, image, size, true, 0, 0, x, y, width, height);
|
||||||
}
|
}
|
||||||
@ -659,12 +659,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
||||||
{
|
{
|
||||||
_gd.PipelineInternal.EndRenderPass();
|
_gd.PipelineInternal.EndRenderPass();
|
||||||
var cbs = _gd.PipelineInternal.CurrentCommandBuffer;
|
CommandBufferScoped cbs = _gd.PipelineInternal.CurrentCommandBuffer;
|
||||||
|
|
||||||
int outSize = Info.GetMipSize(level);
|
int outSize = Info.GetMipSize(level);
|
||||||
int hostSize = GetBufferDataLength(outSize);
|
int hostSize = GetBufferDataLength(outSize);
|
||||||
|
|
||||||
var image = GetImage().Get(cbs).Value;
|
Image image = GetImage().Get(cbs).Value;
|
||||||
int offset = range.Offset;
|
int offset = range.Offset;
|
||||||
|
|
||||||
Auto<DisposableBuffer> autoBuffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, range.Handle, true);
|
Auto<DisposableBuffer> autoBuffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, range.Handle, true);
|
||||||
@ -773,7 +773,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
int bufferDataLength = GetBufferDataLength(data.Length);
|
int bufferDataLength = GetBufferDataLength(data.Length);
|
||||||
|
|
||||||
using var bufferHolder = _gd.BufferManager.Create(_gd, bufferDataLength);
|
using BufferHolder bufferHolder = _gd.BufferManager.Create(_gd, bufferDataLength);
|
||||||
|
|
||||||
Auto<DisposableImage> imageAuto = GetImage();
|
Auto<DisposableImage> imageAuto = GetImage();
|
||||||
|
|
||||||
@ -781,7 +781,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
bool loadInline = Storage.HasCommandBufferDependency(_gd.PipelineInternal.CurrentCommandBuffer);
|
bool loadInline = Storage.HasCommandBufferDependency(_gd.PipelineInternal.CurrentCommandBuffer);
|
||||||
|
|
||||||
var cbs = loadInline ? _gd.PipelineInternal.CurrentCommandBuffer : _gd.PipelineInternal.GetPreloadCommandBuffer();
|
CommandBufferScoped cbs = loadInline ? _gd.PipelineInternal.CurrentCommandBuffer : _gd.PipelineInternal.GetPreloadCommandBuffer();
|
||||||
|
|
||||||
if (loadInline)
|
if (loadInline)
|
||||||
{
|
{
|
||||||
@ -790,8 +790,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
CopyDataToBuffer(bufferHolder.GetDataStorage(0, bufferDataLength), data);
|
CopyDataToBuffer(bufferHolder.GetDataStorage(0, bufferDataLength), data);
|
||||||
|
|
||||||
var buffer = bufferHolder.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
VkBuffer buffer = bufferHolder.GetBuffer(cbs.CommandBuffer).Get(cbs).Value;
|
||||||
var image = imageAuto.Get(cbs).Value;
|
Image image = imageAuto.Get(cbs).Value;
|
||||||
|
|
||||||
if (region.HasValue)
|
if (region.HasValue)
|
||||||
{
|
{
|
||||||
@ -927,24 +927,24 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
int rowLength = ((stride == 0 ? Info.GetMipStride(dstLevel + level) : stride) / Info.BytesPerPixel) * Info.BlockWidth;
|
int rowLength = ((stride == 0 ? Info.GetMipStride(dstLevel + level) : stride) / Info.BytesPerPixel) * Info.BlockWidth;
|
||||||
|
|
||||||
var aspectFlags = Info.Format.ConvertAspectFlags();
|
ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
if (aspectFlags == (ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit))
|
if (aspectFlags == (ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit))
|
||||||
{
|
{
|
||||||
aspectFlags = ImageAspectFlags.DepthBit;
|
aspectFlags = ImageAspectFlags.DepthBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sl = new ImageSubresourceLayers(
|
ImageSubresourceLayers sl = new ImageSubresourceLayers(
|
||||||
aspectFlags,
|
aspectFlags,
|
||||||
(uint)(FirstLevel + dstLevel + level),
|
(uint)(FirstLevel + dstLevel + level),
|
||||||
(uint)(FirstLayer + layer),
|
(uint)(FirstLayer + layer),
|
||||||
(uint)layers);
|
(uint)layers);
|
||||||
|
|
||||||
var extent = new Extent3D((uint)width, (uint)height, (uint)depth);
|
Extent3D extent = new Extent3D((uint)width, (uint)height, (uint)depth);
|
||||||
|
|
||||||
int z = is3D ? dstLayer : 0;
|
int z = is3D ? dstLayer : 0;
|
||||||
|
|
||||||
var region = new BufferImageCopy(
|
BufferImageCopy region = new BufferImageCopy(
|
||||||
(ulong)offset,
|
(ulong)offset,
|
||||||
(uint)AlignUpNpot(rowLength, Info.BlockWidth),
|
(uint)AlignUpNpot(rowLength, Info.BlockWidth),
|
||||||
(uint)AlignUpNpot(height, Info.BlockHeight),
|
(uint)AlignUpNpot(height, Info.BlockHeight),
|
||||||
@ -986,16 +986,16 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
{
|
{
|
||||||
var aspectFlags = Info.Format.ConvertAspectFlags();
|
ImageAspectFlags aspectFlags = Info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
if (aspectFlags == (ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit))
|
if (aspectFlags == (ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit))
|
||||||
{
|
{
|
||||||
aspectFlags = ImageAspectFlags.DepthBit;
|
aspectFlags = ImageAspectFlags.DepthBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sl = new ImageSubresourceLayers(aspectFlags, (uint)(FirstLevel + dstLevel), (uint)(FirstLayer + dstLayer), 1);
|
ImageSubresourceLayers sl = new ImageSubresourceLayers(aspectFlags, (uint)(FirstLevel + dstLevel), (uint)(FirstLayer + dstLayer), 1);
|
||||||
|
|
||||||
var extent = new Extent3D((uint)width, (uint)height, 1);
|
Extent3D extent = new Extent3D((uint)width, (uint)height, 1);
|
||||||
|
|
||||||
int rowLengthAlignment = Info.BlockWidth;
|
int rowLengthAlignment = Info.BlockWidth;
|
||||||
|
|
||||||
@ -1005,7 +1005,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
rowLengthAlignment = 4 / Info.BytesPerPixel;
|
rowLengthAlignment = 4 / Info.BytesPerPixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
var region = new BufferImageCopy(
|
BufferImageCopy region = new BufferImageCopy(
|
||||||
0,
|
0,
|
||||||
(uint)AlignUpNpot(width, rowLengthAlignment),
|
(uint)AlignUpNpot(width, rowLengthAlignment),
|
||||||
(uint)AlignUpNpot(height, Info.BlockHeight),
|
(uint)AlignUpNpot(height, Info.BlockHeight),
|
||||||
@ -1073,7 +1073,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
CommandBufferScoped cbs,
|
CommandBufferScoped cbs,
|
||||||
FramebufferParams fb)
|
FramebufferParams fb)
|
||||||
{
|
{
|
||||||
var key = fb.GetRenderPassCacheKey();
|
RenderPassCacheKey key = fb.GetRenderPassCacheKey();
|
||||||
|
|
||||||
if (_renderPasses == null || !_renderPasses.TryGetValue(ref key, out RenderPassHolder rpHolder))
|
if (_renderPasses == null || !_renderPasses.TryGetValue(ref key, out RenderPassHolder rpHolder))
|
||||||
{
|
{
|
||||||
@ -1121,9 +1121,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (_renderPasses != null)
|
if (_renderPasses != null)
|
||||||
{
|
{
|
||||||
var renderPasses = _renderPasses.Values.ToArray();
|
RenderPassHolder[] renderPasses = _renderPasses.Values.ToArray();
|
||||||
|
|
||||||
foreach (var pass in renderPasses)
|
foreach (RenderPassHolder pass in renderPasses)
|
||||||
{
|
{
|
||||||
pass.Dispose();
|
pass.Dispose();
|
||||||
}
|
}
|
||||||
@ -1131,7 +1131,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (_selfManagedViews != null)
|
if (_selfManagedViews != null)
|
||||||
{
|
{
|
||||||
foreach (var view in _selfManagedViews.Values)
|
foreach (TextureView view in _selfManagedViews.Values)
|
||||||
{
|
{
|
||||||
view.Dispose();
|
view.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Silk.NET.Vulkan;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
@ -50,7 +51,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
public void BindVertexBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding, ref PipelineState state, VertexBufferUpdater updater)
|
public void BindVertexBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding, ref PipelineState state, VertexBufferUpdater updater)
|
||||||
{
|
{
|
||||||
var autoBuffer = _buffer;
|
Auto<DisposableBuffer> autoBuffer = _buffer;
|
||||||
|
|
||||||
if (_handle != BufferHandle.Null)
|
if (_handle != BufferHandle.Null)
|
||||||
{
|
{
|
||||||
@ -67,7 +68,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
int stride = (_stride + (alignment - 1)) & -alignment;
|
int stride = (_stride + (alignment - 1)) & -alignment;
|
||||||
int newSize = (_size / _stride) * stride;
|
int newSize = (_size / _stride) * stride;
|
||||||
|
|
||||||
var buffer = autoBuffer.Get(cbs, 0, newSize).Value;
|
Buffer buffer = autoBuffer.Get(cbs, 0, newSize).Value;
|
||||||
|
|
||||||
updater.BindVertexBuffer(cbs, binding, buffer, 0, (ulong)newSize, (ulong)stride);
|
updater.BindVertexBuffer(cbs, binding, buffer, 0, (ulong)newSize, (ulong)stride);
|
||||||
|
|
||||||
@ -94,7 +95,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
int offset = _offset;
|
int offset = _offset;
|
||||||
bool mirrorable = _size <= VertexBufferMaxMirrorable;
|
bool mirrorable = _size <= VertexBufferMaxMirrorable;
|
||||||
var buffer = mirrorable ? autoBuffer.GetMirrorable(cbs, ref offset, _size, out _).Value : autoBuffer.Get(cbs, offset, _size).Value;
|
Buffer buffer = mirrorable ? autoBuffer.GetMirrorable(cbs, ref offset, _size, out _).Value : autoBuffer.Get(cbs, offset, _size).Value;
|
||||||
|
|
||||||
updater.BindVertexBuffer(cbs, binding, buffer, (ulong)offset, (ulong)_size, (ulong)_stride);
|
updater.BindVertexBuffer(cbs, binding, buffer, (ulong)offset, (ulong)_size, (ulong)_stride);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (_debugUtils != null && _logLevel != GraphicsDebugLevel.None)
|
if (_debugUtils != null && _logLevel != GraphicsDebugLevel.None)
|
||||||
{
|
{
|
||||||
var messageType = _logLevel switch
|
DebugUtilsMessageTypeFlagsEXT messageType = _logLevel switch
|
||||||
{
|
{
|
||||||
GraphicsDebugLevel.Error => DebugUtilsMessageTypeFlagsEXT.ValidationBitExt,
|
GraphicsDebugLevel.Error => DebugUtilsMessageTypeFlagsEXT.ValidationBitExt,
|
||||||
GraphicsDebugLevel.Slowdowns => DebugUtilsMessageTypeFlagsEXT.ValidationBitExt |
|
GraphicsDebugLevel.Slowdowns => DebugUtilsMessageTypeFlagsEXT.ValidationBitExt |
|
||||||
@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
var messageSeverity = _logLevel switch
|
DebugUtilsMessageSeverityFlagsEXT messageSeverity = _logLevel switch
|
||||||
{
|
{
|
||||||
GraphicsDebugLevel.Error => DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt,
|
GraphicsDebugLevel.Error => DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt,
|
||||||
GraphicsDebugLevel.Slowdowns => DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt |
|
GraphicsDebugLevel.Slowdowns => DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt |
|
||||||
@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
var debugUtilsMessengerCreateInfo = new DebugUtilsMessengerCreateInfoEXT
|
DebugUtilsMessengerCreateInfoEXT debugUtilsMessengerCreateInfo = new DebugUtilsMessengerCreateInfoEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.DebugUtilsMessengerCreateInfoExt,
|
SType = StructureType.DebugUtilsMessengerCreateInfoExt,
|
||||||
MessageType = messageType,
|
MessageType = messageType,
|
||||||
@ -95,7 +95,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
DebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
DebugUtilsMessengerCallbackDataEXT* pCallbackData,
|
||||||
void* pUserData)
|
void* pUserData)
|
||||||
{
|
{
|
||||||
var msg = Marshal.PtrToStringAnsi((nint)pCallbackData->PMessage);
|
string msg = Marshal.PtrToStringAnsi((nint)pCallbackData->PMessage);
|
||||||
|
|
||||||
if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt))
|
if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt))
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using Silk.NET.Core;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using Silk.NET.Vulkan.Extensions.EXT;
|
using Silk.NET.Vulkan.Extensions.EXT;
|
||||||
using Silk.NET.Vulkan.Extensions.KHR;
|
using Silk.NET.Vulkan.Extensions.KHR;
|
||||||
@ -54,10 +55,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
internal static VulkanInstance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions)
|
internal static VulkanInstance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions)
|
||||||
{
|
{
|
||||||
var enabledLayers = new List<string>();
|
List<string> enabledLayers = new List<string>();
|
||||||
|
|
||||||
var instanceExtensions = VulkanInstance.GetInstanceExtensions(api);
|
IReadOnlySet<string> instanceExtensions = VulkanInstance.GetInstanceExtensions(api);
|
||||||
var instanceLayers = VulkanInstance.GetInstanceLayers(api);
|
IReadOnlySet<string> instanceLayers = VulkanInstance.GetInstanceLayers(api);
|
||||||
|
|
||||||
void AddAvailableLayer(string layerName)
|
void AddAvailableLayer(string layerName)
|
||||||
{
|
{
|
||||||
@ -76,16 +77,16 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
AddAvailableLayer("VK_LAYER_KHRONOS_validation");
|
AddAvailableLayer("VK_LAYER_KHRONOS_validation");
|
||||||
}
|
}
|
||||||
|
|
||||||
var enabledExtensions = requiredExtensions;
|
string[] enabledExtensions = requiredExtensions;
|
||||||
|
|
||||||
if (instanceExtensions.Contains("VK_EXT_debug_utils"))
|
if (instanceExtensions.Contains("VK_EXT_debug_utils"))
|
||||||
{
|
{
|
||||||
enabledExtensions = enabledExtensions.Append(ExtDebugUtils.ExtensionName).ToArray();
|
enabledExtensions = enabledExtensions.Append(ExtDebugUtils.ExtensionName).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
var appName = Marshal.StringToHGlobalAnsi(AppName);
|
IntPtr appName = Marshal.StringToHGlobalAnsi(AppName);
|
||||||
|
|
||||||
var applicationInfo = new ApplicationInfo
|
ApplicationInfo applicationInfo = new ApplicationInfo
|
||||||
{
|
{
|
||||||
PApplicationName = (byte*)appName,
|
PApplicationName = (byte*)appName,
|
||||||
ApplicationVersion = 1,
|
ApplicationVersion = 1,
|
||||||
@ -107,7 +108,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ppEnabledLayers[i] = Marshal.StringToHGlobalAnsi(enabledLayers[i]);
|
ppEnabledLayers[i] = Marshal.StringToHGlobalAnsi(enabledLayers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var instanceCreateInfo = new InstanceCreateInfo
|
InstanceCreateInfo instanceCreateInfo = new InstanceCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.InstanceCreateInfo,
|
SType = StructureType.InstanceCreateInfo,
|
||||||
PApplicationInfo = &applicationInfo,
|
PApplicationInfo = &applicationInfo,
|
||||||
@ -117,7 +118,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
EnabledLayerCount = (uint)enabledLayers.Count,
|
EnabledLayerCount = (uint)enabledLayers.Count,
|
||||||
};
|
};
|
||||||
|
|
||||||
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out var instance);
|
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out VulkanInstance instance);
|
||||||
|
|
||||||
Marshal.FreeHGlobal(appName);
|
Marshal.FreeHGlobal(appName);
|
||||||
|
|
||||||
@ -138,7 +139,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
internal static VulkanPhysicalDevice FindSuitablePhysicalDevice(Vk api, VulkanInstance instance, SurfaceKHR surface, string preferredGpuId)
|
internal static VulkanPhysicalDevice FindSuitablePhysicalDevice(Vk api, VulkanInstance instance, SurfaceKHR surface, string preferredGpuId)
|
||||||
{
|
{
|
||||||
instance.EnumeratePhysicalDevices(out var physicalDevices).ThrowOnError();
|
instance.EnumeratePhysicalDevices(out VulkanPhysicalDevice[] physicalDevices).ThrowOnError();
|
||||||
|
|
||||||
// First we try to pick the user preferred GPU.
|
// First we try to pick the user preferred GPU.
|
||||||
for (int i = 0; i < physicalDevices.Length; i++)
|
for (int i = 0; i < physicalDevices.Length; i++)
|
||||||
@ -163,9 +164,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
internal static DeviceInfo[] GetSuitablePhysicalDevices(Vk api)
|
internal static DeviceInfo[] GetSuitablePhysicalDevices(Vk api)
|
||||||
{
|
{
|
||||||
var appName = Marshal.StringToHGlobalAnsi(AppName);
|
IntPtr appName = Marshal.StringToHGlobalAnsi(AppName);
|
||||||
|
|
||||||
var applicationInfo = new ApplicationInfo
|
ApplicationInfo applicationInfo = new ApplicationInfo
|
||||||
{
|
{
|
||||||
PApplicationName = (byte*)appName,
|
PApplicationName = (byte*)appName,
|
||||||
ApplicationVersion = 1,
|
ApplicationVersion = 1,
|
||||||
@ -174,7 +175,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ApiVersion = _maximumVulkanVersion,
|
ApiVersion = _maximumVulkanVersion,
|
||||||
};
|
};
|
||||||
|
|
||||||
var instanceCreateInfo = new InstanceCreateInfo
|
InstanceCreateInfo instanceCreateInfo = new InstanceCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.InstanceCreateInfo,
|
SType = StructureType.InstanceCreateInfo,
|
||||||
PApplicationInfo = &applicationInfo,
|
PApplicationInfo = &applicationInfo,
|
||||||
@ -184,7 +185,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
EnabledLayerCount = 0,
|
EnabledLayerCount = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out var rawInstance);
|
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out VulkanInstance rawInstance);
|
||||||
|
|
||||||
Marshal.FreeHGlobal(appName);
|
Marshal.FreeHGlobal(appName);
|
||||||
|
|
||||||
@ -245,13 +246,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
{
|
{
|
||||||
const QueueFlags RequiredFlags = QueueFlags.GraphicsBit | QueueFlags.ComputeBit;
|
const QueueFlags RequiredFlags = QueueFlags.GraphicsBit | QueueFlags.ComputeBit;
|
||||||
|
|
||||||
var khrSurface = new KhrSurface(api.Context);
|
KhrSurface khrSurface = new KhrSurface(api.Context);
|
||||||
|
|
||||||
for (uint index = 0; index < physicalDevice.QueueFamilyProperties.Length; index++)
|
for (uint index = 0; index < physicalDevice.QueueFamilyProperties.Length; index++)
|
||||||
{
|
{
|
||||||
ref QueueFamilyProperties property = ref physicalDevice.QueueFamilyProperties[index];
|
ref QueueFamilyProperties property = ref physicalDevice.QueueFamilyProperties[index];
|
||||||
|
|
||||||
khrSurface.GetPhysicalDeviceSurfaceSupport(physicalDevice.PhysicalDevice, index, surface, out var surfaceSupported).ThrowOnError();
|
khrSurface.GetPhysicalDeviceSurfaceSupport(physicalDevice.PhysicalDevice, index, surface, out Bool32 surfaceSupported).ThrowOnError();
|
||||||
|
|
||||||
if (property.QueueFlags.HasFlag(RequiredFlags) && surfaceSupported)
|
if (property.QueueFlags.HasFlag(RequiredFlags) && surfaceSupported)
|
||||||
{
|
{
|
||||||
@ -280,7 +281,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
queuePriorities[i] = 1f;
|
queuePriorities[i] = 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
var queueCreateInfo = new DeviceQueueCreateInfo
|
DeviceQueueCreateInfo queueCreateInfo = new DeviceQueueCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DeviceQueueCreateInfo,
|
SType = StructureType.DeviceQueueCreateInfo,
|
||||||
QueueFamilyIndex = queueFamilyIndex,
|
QueueFamilyIndex = queueFamilyIndex,
|
||||||
@ -391,9 +392,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
api.GetPhysicalDeviceFeatures2(physicalDevice.PhysicalDevice, &features2);
|
api.GetPhysicalDeviceFeatures2(physicalDevice.PhysicalDevice, &features2);
|
||||||
|
|
||||||
var supportedFeatures = features2.Features;
|
PhysicalDeviceFeatures supportedFeatures = features2.Features;
|
||||||
|
|
||||||
var features = new PhysicalDeviceFeatures
|
PhysicalDeviceFeatures features = new PhysicalDeviceFeatures
|
||||||
{
|
{
|
||||||
DepthBiasClamp = supportedFeatures.DepthBiasClamp,
|
DepthBiasClamp = supportedFeatures.DepthBiasClamp,
|
||||||
DepthClamp = supportedFeatures.DepthClamp,
|
DepthClamp = supportedFeatures.DepthClamp,
|
||||||
@ -464,7 +465,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
pExtendedFeatures = &featuresRobustness2;
|
pExtendedFeatures = &featuresRobustness2;
|
||||||
}
|
}
|
||||||
|
|
||||||
var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT
|
PhysicalDeviceExtendedDynamicStateFeaturesEXT featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt,
|
SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
@ -473,7 +474,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
pExtendedFeatures = &featuresExtendedDynamicState;
|
pExtendedFeatures = &featuresExtendedDynamicState;
|
||||||
|
|
||||||
var featuresVk11 = new PhysicalDeviceVulkan11Features
|
PhysicalDeviceVulkan11Features featuresVk11 = new PhysicalDeviceVulkan11Features
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
@ -482,7 +483,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
pExtendedFeatures = &featuresVk11;
|
pExtendedFeatures = &featuresVk11;
|
||||||
|
|
||||||
var featuresVk12 = new PhysicalDeviceVulkan12Features
|
PhysicalDeviceVulkan12Features featuresVk12 = new PhysicalDeviceVulkan12Features
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan12Features,
|
SType = StructureType.PhysicalDeviceVulkan12Features,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
@ -585,7 +586,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
pExtendedFeatures = &featuresDynamicAttachmentFeedbackLoopLayout;
|
pExtendedFeatures = &featuresDynamicAttachmentFeedbackLoopLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
var enabledExtensions = _requiredExtensions.Union(_desirableExtensions.Intersect(physicalDevice.DeviceExtensions)).ToArray();
|
string[] enabledExtensions = _requiredExtensions.Union(_desirableExtensions.Intersect(physicalDevice.DeviceExtensions)).ToArray();
|
||||||
|
|
||||||
nint* ppEnabledExtensions = stackalloc nint[enabledExtensions.Length];
|
nint* ppEnabledExtensions = stackalloc nint[enabledExtensions.Length];
|
||||||
|
|
||||||
@ -594,7 +595,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
|
ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var deviceCreateInfo = new DeviceCreateInfo
|
DeviceCreateInfo deviceCreateInfo = new DeviceCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DeviceCreateInfo,
|
SType = StructureType.DeviceCreateInfo,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
@ -605,7 +606,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PEnabledFeatures = &features,
|
PEnabledFeatures = &features,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CreateDevice(physicalDevice.PhysicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();
|
api.CreateDevice(physicalDevice.PhysicalDevice, in deviceCreateInfo, null, out Device device).ThrowOnError();
|
||||||
|
|
||||||
for (int i = 0; i < enabledExtensions.Length; i++)
|
for (int i = 0; i < enabledExtensions.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
PhysicalDevice = physicalDevice;
|
PhysicalDevice = physicalDevice;
|
||||||
PhysicalDeviceFeatures = api.GetPhysicalDeviceFeature(PhysicalDevice);
|
PhysicalDeviceFeatures = api.GetPhysicalDeviceFeature(PhysicalDevice);
|
||||||
|
|
||||||
api.GetPhysicalDeviceProperties(PhysicalDevice, out var physicalDeviceProperties);
|
api.GetPhysicalDeviceProperties(PhysicalDevice, out PhysicalDeviceProperties physicalDeviceProperties);
|
||||||
PhysicalDeviceProperties = physicalDeviceProperties;
|
PhysicalDeviceProperties = physicalDeviceProperties;
|
||||||
|
|
||||||
api.GetPhysicalDeviceMemoryProperties(PhysicalDevice, out PhysicalDeviceMemoryProperties);
|
api.GetPhysicalDeviceMemoryProperties(PhysicalDevice, out PhysicalDeviceMemoryProperties);
|
||||||
|
@ -12,6 +12,7 @@ using Silk.NET.Vulkan.Extensions.KHR;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Format = Ryujinx.Graphics.GAL.Format;
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
||||||
@ -163,7 +164,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (maxQueueCount >= 2)
|
if (maxQueueCount >= 2)
|
||||||
{
|
{
|
||||||
Api.GetDeviceQueue(_device, queueFamilyIndex, 1, out var backgroundQueue);
|
Api.GetDeviceQueue(_device, queueFamilyIndex, 1, out Queue backgroundQueue);
|
||||||
BackgroundQueue = backgroundQueue;
|
BackgroundQueue = backgroundQueue;
|
||||||
BackgroundQueueLock = new();
|
BackgroundQueueLock = new();
|
||||||
}
|
}
|
||||||
@ -331,7 +332,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Api.GetPhysicalDeviceProperties2(_physicalDevice.PhysicalDevice, &properties2);
|
Api.GetPhysicalDeviceProperties2(_physicalDevice.PhysicalDevice, &properties2);
|
||||||
Api.GetPhysicalDeviceFeatures2(_physicalDevice.PhysicalDevice, &features2);
|
Api.GetPhysicalDeviceFeatures2(_physicalDevice.PhysicalDevice, &features2);
|
||||||
|
|
||||||
var portabilityFlags = PortabilitySubsetFlags.None;
|
PortabilitySubsetFlags portabilityFlags = PortabilitySubsetFlags.None;
|
||||||
uint vertexBufferAlignment = 1;
|
uint vertexBufferAlignment = 1;
|
||||||
|
|
||||||
if (usePortability)
|
if (usePortability)
|
||||||
@ -348,9 +349,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
featuresCustomBorderColor.CustomBorderColors &&
|
featuresCustomBorderColor.CustomBorderColors &&
|
||||||
featuresCustomBorderColor.CustomBorderColorWithoutFormat;
|
featuresCustomBorderColor.CustomBorderColorWithoutFormat;
|
||||||
|
|
||||||
ref var properties = ref properties2.Properties;
|
ref PhysicalDeviceProperties properties = ref properties2.Properties;
|
||||||
|
|
||||||
var hasDriverProperties = _physicalDevice.TryGetPhysicalDeviceDriverPropertiesKHR(Api, out var driverProperties);
|
bool hasDriverProperties = _physicalDevice.TryGetPhysicalDeviceDriverPropertiesKHR(Api, out PhysicalDeviceDriverPropertiesKHR driverProperties);
|
||||||
|
|
||||||
Vendor = VendorUtils.FromId(properties.VendorID);
|
Vendor = VendorUtils.FromId(properties.VendorID);
|
||||||
|
|
||||||
@ -378,7 +379,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
if (Vendor == Vendor.Nvidia)
|
if (Vendor == Vendor.Nvidia)
|
||||||
{
|
{
|
||||||
var match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer);
|
Match match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer);
|
||||||
|
|
||||||
if (match != null && int.TryParse(match.Groups[2].Value, out int gpuNumber))
|
if (match != null && int.TryParse(match.Groups[2].Value, out int gpuNumber))
|
||||||
{
|
{
|
||||||
@ -487,7 +488,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_surface = _getSurface(_instance.Instance, Api);
|
_surface = _getSurface(_instance.Instance, Api);
|
||||||
_physicalDevice = VulkanInitialization.FindSuitablePhysicalDevice(Api, _instance, _surface, _preferredGpuId);
|
_physicalDevice = VulkanInitialization.FindSuitablePhysicalDevice(Api, _instance, _surface, _preferredGpuId);
|
||||||
|
|
||||||
var queueFamilyIndex = VulkanInitialization.FindSuitableQueueFamily(Api, _physicalDevice, _surface, out uint maxQueueCount);
|
uint queueFamilyIndex = VulkanInitialization.FindSuitableQueueFamily(Api, _physicalDevice, _surface, out uint maxQueueCount);
|
||||||
|
|
||||||
_device = VulkanInitialization.CreateDevice(Api, _physicalDevice, queueFamilyIndex, maxQueueCount);
|
_device = VulkanInitialization.CreateDevice(Api, _physicalDevice, queueFamilyIndex, maxQueueCount);
|
||||||
|
|
||||||
@ -496,7 +497,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SwapchainApi = swapchainApi;
|
SwapchainApi = swapchainApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
Api.GetDeviceQueue(_device, queueFamilyIndex, 0, out var queue);
|
Api.GetDeviceQueue(_device, queueFamilyIndex, 0, out Queue queue);
|
||||||
Queue = queue;
|
Queue = queue;
|
||||||
QueueLock = new();
|
QueueLock = new();
|
||||||
|
|
||||||
@ -590,7 +591,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
internal TextureView CreateTextureView(TextureCreateInfo info)
|
internal TextureView CreateTextureView(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
// This should be disposed when all views are destroyed.
|
// This should be disposed when all views are destroyed.
|
||||||
var storage = CreateTextureStorage(info);
|
TextureStorage storage = CreateTextureStorage(info);
|
||||||
return storage.CreateView(info, 0, 0);
|
return storage.CreateView(info, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -713,8 +714,8 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
Api.GetPhysicalDeviceFeatures2(_physicalDevice.PhysicalDevice, &features2);
|
Api.GetPhysicalDeviceFeatures2(_physicalDevice.PhysicalDevice, &features2);
|
||||||
|
|
||||||
var limits = _physicalDevice.PhysicalDeviceProperties.Limits;
|
PhysicalDeviceLimits limits = _physicalDevice.PhysicalDeviceProperties.Limits;
|
||||||
var mainQueueProperties = _physicalDevice.QueueFamilyProperties[QueueFamilyIndex];
|
QueueFamilyProperties mainQueueProperties = _physicalDevice.QueueFamilyProperties[QueueFamilyIndex];
|
||||||
|
|
||||||
SystemMemoryType memoryType;
|
SystemMemoryType memoryType;
|
||||||
|
|
||||||
@ -801,7 +802,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
for (int i = 0; i < memoryProperties.MemoryHeapCount; i++)
|
for (int i = 0; i < memoryProperties.MemoryHeapCount; i++)
|
||||||
{
|
{
|
||||||
var heap = memoryProperties.MemoryHeaps[i];
|
MemoryHeap heap = memoryProperties.MemoryHeaps[i];
|
||||||
if ((heap.Flags & MemoryHeapFlags.DeviceLocalBit) == MemoryHeapFlags.DeviceLocalBit)
|
if ((heap.Flags & MemoryHeapFlags.DeviceLocalBit) == MemoryHeapFlags.DeviceLocalBit)
|
||||||
{
|
{
|
||||||
totalMemory += heap.Size;
|
totalMemory += heap.Size;
|
||||||
@ -1030,17 +1031,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
MemoryAllocator.Dispose();
|
MemoryAllocator.Dispose();
|
||||||
|
|
||||||
foreach (var shader in Shaders)
|
foreach (ShaderCollection shader in Shaders)
|
||||||
{
|
{
|
||||||
shader.Dispose();
|
shader.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var texture in Textures)
|
foreach (ITexture texture in Textures)
|
||||||
{
|
{
|
||||||
texture.Release();
|
texture.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var sampler in Samplers)
|
foreach (SamplerHolder sampler in Samplers)
|
||||||
{
|
{
|
||||||
sampler.Dispose();
|
sampler.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private void RecreateSwapchain()
|
private void RecreateSwapchain()
|
||||||
{
|
{
|
||||||
var oldSwapchain = _swapchain;
|
SwapchainKHR oldSwapchain = _swapchain;
|
||||||
_swapchainIsDirty = false;
|
_swapchainIsDirty = false;
|
||||||
|
|
||||||
for (int i = 0; i < _swapchainImageViews.Length; i++)
|
for (int i = 0; i < _swapchainImageViews.Length; i++)
|
||||||
@ -87,13 +87,13 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private unsafe void CreateSwapchain()
|
private unsafe void CreateSwapchain()
|
||||||
{
|
{
|
||||||
_gd.SurfaceApi.GetPhysicalDeviceSurfaceCapabilities(_physicalDevice, _surface, out var capabilities);
|
_gd.SurfaceApi.GetPhysicalDeviceSurfaceCapabilities(_physicalDevice, _surface, out SurfaceCapabilitiesKHR capabilities);
|
||||||
|
|
||||||
uint surfaceFormatsCount;
|
uint surfaceFormatsCount;
|
||||||
|
|
||||||
_gd.SurfaceApi.GetPhysicalDeviceSurfaceFormats(_physicalDevice, _surface, &surfaceFormatsCount, null);
|
_gd.SurfaceApi.GetPhysicalDeviceSurfaceFormats(_physicalDevice, _surface, &surfaceFormatsCount, null);
|
||||||
|
|
||||||
var surfaceFormats = new SurfaceFormatKHR[surfaceFormatsCount];
|
SurfaceFormatKHR[] surfaceFormats = new SurfaceFormatKHR[surfaceFormatsCount];
|
||||||
|
|
||||||
fixed (SurfaceFormatKHR* pSurfaceFormats = surfaceFormats)
|
fixed (SurfaceFormatKHR* pSurfaceFormats = surfaceFormats)
|
||||||
{
|
{
|
||||||
@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
_gd.SurfaceApi.GetPhysicalDeviceSurfacePresentModes(_physicalDevice, _surface, &presentModesCount, null);
|
_gd.SurfaceApi.GetPhysicalDeviceSurfacePresentModes(_physicalDevice, _surface, &presentModesCount, null);
|
||||||
|
|
||||||
var presentModes = new PresentModeKHR[presentModesCount];
|
PresentModeKHR[] presentModes = new PresentModeKHR[presentModesCount];
|
||||||
|
|
||||||
fixed (PresentModeKHR* pPresentModes = presentModes)
|
fixed (PresentModeKHR* pPresentModes = presentModes)
|
||||||
{
|
{
|
||||||
@ -117,17 +117,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
imageCount = capabilities.MaxImageCount;
|
imageCount = capabilities.MaxImageCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
var surfaceFormat = ChooseSwapSurfaceFormat(surfaceFormats, _colorSpacePassthroughEnabled);
|
SurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(surfaceFormats, _colorSpacePassthroughEnabled);
|
||||||
|
|
||||||
var extent = ChooseSwapExtent(capabilities);
|
Extent2D extent = ChooseSwapExtent(capabilities);
|
||||||
|
|
||||||
_width = (int)extent.Width;
|
_width = (int)extent.Width;
|
||||||
_height = (int)extent.Height;
|
_height = (int)extent.Height;
|
||||||
_format = surfaceFormat.Format;
|
_format = surfaceFormat.Format;
|
||||||
|
|
||||||
var oldSwapchain = _swapchain;
|
SwapchainKHR oldSwapchain = _swapchain;
|
||||||
|
|
||||||
var swapchainCreateInfo = new SwapchainCreateInfoKHR
|
SwapchainCreateInfoKHR swapchainCreateInfo = new SwapchainCreateInfoKHR
|
||||||
{
|
{
|
||||||
SType = StructureType.SwapchainCreateInfoKhr,
|
SType = StructureType.SwapchainCreateInfoKhr,
|
||||||
Surface = _surface,
|
Surface = _surface,
|
||||||
@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
Clipped = true,
|
Clipped = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
var textureCreateInfo = new TextureCreateInfo(
|
TextureCreateInfo textureCreateInfo = new TextureCreateInfo(
|
||||||
_width,
|
_width,
|
||||||
_height,
|
_height,
|
||||||
1,
|
1,
|
||||||
@ -179,7 +179,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
_swapchainImageViews[i] = CreateSwapchainImageView(_swapchainImages[i], surfaceFormat.Format, textureCreateInfo);
|
_swapchainImageViews[i] = CreateSwapchainImageView(_swapchainImages[i], surfaceFormat.Format, textureCreateInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
var semaphoreCreateInfo = new SemaphoreCreateInfo
|
SemaphoreCreateInfo semaphoreCreateInfo = new SemaphoreCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.SemaphoreCreateInfo,
|
SType = StructureType.SemaphoreCreateInfo,
|
||||||
};
|
};
|
||||||
@ -201,17 +201,17 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
private unsafe TextureView CreateSwapchainImageView(Image swapchainImage, VkFormat format, TextureCreateInfo info)
|
private unsafe TextureView CreateSwapchainImageView(Image swapchainImage, VkFormat format, TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
var componentMapping = new ComponentMapping(
|
ComponentMapping componentMapping = new ComponentMapping(
|
||||||
ComponentSwizzle.R,
|
ComponentSwizzle.R,
|
||||||
ComponentSwizzle.G,
|
ComponentSwizzle.G,
|
||||||
ComponentSwizzle.B,
|
ComponentSwizzle.B,
|
||||||
ComponentSwizzle.A);
|
ComponentSwizzle.A);
|
||||||
|
|
||||||
var aspectFlags = ImageAspectFlags.ColorBit;
|
ImageAspectFlags aspectFlags = ImageAspectFlags.ColorBit;
|
||||||
|
|
||||||
var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, 1, 0, 1);
|
ImageSubresourceRange subresourceRange = new ImageSubresourceRange(aspectFlags, 0, 1, 0, 1);
|
||||||
|
|
||||||
var imageCreateInfo = new ImageViewCreateInfo
|
ImageViewCreateInfo imageCreateInfo = new ImageViewCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageViewCreateInfo,
|
SType = StructureType.ImageViewCreateInfo,
|
||||||
Image = swapchainImage,
|
Image = swapchainImage,
|
||||||
@ -221,7 +221,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
SubresourceRange = subresourceRange,
|
SubresourceRange = subresourceRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.Api.CreateImageView(_device, in imageCreateInfo, null, out var imageView).ThrowOnError();
|
_gd.Api.CreateImageView(_device, in imageCreateInfo, null, out ImageView imageView).ThrowOnError();
|
||||||
|
|
||||||
return new TextureView(_gd, _device, new DisposableImageView(_gd.Api, _device, imageView), info, format);
|
return new TextureView(_gd, _device, new DisposableImageView(_gd.Api, _device, imageView), info, format);
|
||||||
}
|
}
|
||||||
@ -233,10 +233,10 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
return new SurfaceFormatKHR(VkFormat.B8G8R8A8Unorm, ColorSpaceKHR.PaceSrgbNonlinearKhr);
|
return new SurfaceFormatKHR(VkFormat.B8G8R8A8Unorm, ColorSpaceKHR.PaceSrgbNonlinearKhr);
|
||||||
}
|
}
|
||||||
|
|
||||||
var formatToReturn = availableFormats[0];
|
SurfaceFormatKHR formatToReturn = availableFormats[0];
|
||||||
if (colorSpacePassthroughEnabled)
|
if (colorSpacePassthroughEnabled)
|
||||||
{
|
{
|
||||||
foreach (var format in availableFormats)
|
foreach (SurfaceFormatKHR format in availableFormats)
|
||||||
{
|
{
|
||||||
if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.SpacePassThroughExt)
|
if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.SpacePassThroughExt)
|
||||||
{
|
{
|
||||||
@ -251,7 +251,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var format in availableFormats)
|
foreach (SurfaceFormatKHR format in availableFormats)
|
||||||
{
|
{
|
||||||
if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.PaceSrgbNonlinearKhr)
|
if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.PaceSrgbNonlinearKhr)
|
||||||
{
|
{
|
||||||
@ -318,7 +318,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var acquireResult = _gd.SwapchainApi.AcquireNextImage(
|
Result acquireResult = _gd.SwapchainApi.AcquireNextImage(
|
||||||
_device,
|
_device,
|
||||||
_swapchain,
|
_swapchain,
|
||||||
ulong.MaxValue,
|
ulong.MaxValue,
|
||||||
@ -340,11 +340,11 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var swapchainImage = _swapchainImages[nextImage];
|
Image swapchainImage = _swapchainImages[nextImage];
|
||||||
|
|
||||||
_gd.FlushAllCommands();
|
_gd.FlushAllCommands();
|
||||||
|
|
||||||
var cbs = _gd.CommandBufferPool.Rent();
|
CommandBufferScoped cbs = _gd.CommandBufferPool.Rent();
|
||||||
|
|
||||||
Transition(
|
Transition(
|
||||||
cbs.CommandBuffer,
|
cbs.CommandBuffer,
|
||||||
@ -354,7 +354,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ImageLayout.Undefined,
|
ImageLayout.Undefined,
|
||||||
ImageLayout.General);
|
ImageLayout.General);
|
||||||
|
|
||||||
var view = (TextureView)texture;
|
TextureView view = (TextureView)texture;
|
||||||
|
|
||||||
UpdateEffect();
|
UpdateEffect();
|
||||||
|
|
||||||
@ -462,12 +462,12 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
stackalloc[] { _renderFinishedSemaphores[semaphoreIndex] });
|
stackalloc[] { _renderFinishedSemaphores[semaphoreIndex] });
|
||||||
|
|
||||||
// TODO: Present queue.
|
// TODO: Present queue.
|
||||||
var semaphore = _renderFinishedSemaphores[semaphoreIndex];
|
Semaphore semaphore = _renderFinishedSemaphores[semaphoreIndex];
|
||||||
var swapchain = _swapchain;
|
SwapchainKHR swapchain = _swapchain;
|
||||||
|
|
||||||
Result result;
|
Result result;
|
||||||
|
|
||||||
var presentInfo = new PresentInfoKHR
|
PresentInfoKHR presentInfo = new PresentInfoKHR
|
||||||
{
|
{
|
||||||
SType = StructureType.PresentInfoKhr,
|
SType = StructureType.PresentInfoKhr,
|
||||||
WaitSemaphoreCount = 1,
|
WaitSemaphoreCount = 1,
|
||||||
@ -534,7 +534,7 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
case AntiAliasing.SmaaMedium:
|
case AntiAliasing.SmaaMedium:
|
||||||
case AntiAliasing.SmaaHigh:
|
case AntiAliasing.SmaaHigh:
|
||||||
case AntiAliasing.SmaaUltra:
|
case AntiAliasing.SmaaUltra:
|
||||||
var quality = _currentAntiAliasing - AntiAliasing.SmaaLow;
|
int quality = _currentAntiAliasing - AntiAliasing.SmaaLow;
|
||||||
if (_effect is SmaaPostProcessingEffect smaa)
|
if (_effect is SmaaPostProcessingEffect smaa)
|
||||||
{
|
{
|
||||||
smaa.Quality = quality;
|
smaa.Quality = quality;
|
||||||
@ -594,9 +594,9 @@ namespace Ryujinx.Graphics.Vulkan
|
|||||||
ImageLayout srcLayout,
|
ImageLayout srcLayout,
|
||||||
ImageLayout dstLayout)
|
ImageLayout dstLayout)
|
||||||
{
|
{
|
||||||
var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ColorBit, 0, 1, 0, 1);
|
ImageSubresourceRange subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ColorBit, 0, 1, 0, 1);
|
||||||
|
|
||||||
var barrier = new ImageMemoryBarrier
|
ImageMemoryBarrier barrier = new ImageMemoryBarrier
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageMemoryBarrier,
|
SType = StructureType.ImageMemoryBarrier,
|
||||||
SrcAccessMask = srcAccess,
|
SrcAccessMask = srcAccess,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user