[Ryujinx.Graphics.Vulkan] Address dotnet-format issues (#5378)
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0059 warnings * Address dotnet format CA1816 warnings * Fix new dotnet-format issues after rebase * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Format if-blocks correctly * Another rebase, another dotnet format run * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format analyzers after rebase * Run dotnet format style after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Run dotnet format after rebase * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Fix naming rule violations * Remove redundant code * Rename generics * Address review feedback * Remove SetOrigin
This commit is contained in:
parent
12c5f6ee89
commit
801b71a128
72 changed files with 1134 additions and 1230 deletions
|
@ -8,16 +8,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
internal class AutoFlushCounter
|
internal class AutoFlushCounter
|
||||||
{
|
{
|
||||||
// How often to flush on framebuffer change.
|
// How often to flush on framebuffer change.
|
||||||
private readonly static long FramebufferFlushTimer = Stopwatch.Frequency / 1000; // (1ms)
|
private readonly static long _framebufferFlushTimer = Stopwatch.Frequency / 1000; // (1ms)
|
||||||
|
|
||||||
// How often to flush on draw when fast flush mode is enabled.
|
// How often to flush on draw when fast flush mode is enabled.
|
||||||
private readonly static long DrawFlushTimer = Stopwatch.Frequency / 666; // (1.5ms)
|
private readonly static long _drawFlushTimer = Stopwatch.Frequency / 666; // (1.5ms)
|
||||||
|
|
||||||
// Average wait time that triggers fast flush mode to be entered.
|
// Average wait time that triggers fast flush mode to be entered.
|
||||||
private readonly static long FastFlushEnterThreshold = Stopwatch.Frequency / 666; // (1.5ms)
|
private readonly static long _fastFlushEnterThreshold = Stopwatch.Frequency / 666; // (1.5ms)
|
||||||
|
|
||||||
// Average wait time that triggers fast flush mode to be exited.
|
// Average wait time that triggers fast flush mode to be exited.
|
||||||
private readonly static long FastFlushExitThreshold = Stopwatch.Frequency / 10000; // (0.1ms)
|
private readonly static long _fastFlushExitThreshold = Stopwatch.Frequency / 10000; // (0.1ms)
|
||||||
|
|
||||||
// Number of frames to average waiting times over.
|
// Number of frames to average waiting times over.
|
||||||
private const int SyncWaitAverageCount = 20;
|
private const int SyncWaitAverageCount = 20;
|
||||||
|
@ -34,11 +34,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private int _consecutiveQueries;
|
private int _consecutiveQueries;
|
||||||
private int _queryCount;
|
private int _queryCount;
|
||||||
|
|
||||||
private int[] _queryCountHistory = new int[3];
|
private readonly int[] _queryCountHistory = new int[3];
|
||||||
private int _queryCountHistoryIndex;
|
private int _queryCountHistoryIndex;
|
||||||
private int _remainingQueries;
|
private int _remainingQueries;
|
||||||
|
|
||||||
private long[] _syncWaitHistory = new long[SyncWaitAverageCount];
|
private readonly long[] _syncWaitHistory = new long[SyncWaitAverageCount];
|
||||||
private int _syncWaitHistoryIndex;
|
private int _syncWaitHistoryIndex;
|
||||||
|
|
||||||
private bool _fastFlushMode;
|
private bool _fastFlushMode;
|
||||||
|
@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long flushTimeout = DrawFlushTimer;
|
long flushTimeout = _drawFlushTimer;
|
||||||
|
|
||||||
long now = Stopwatch.GetTimestamp();
|
long now = Stopwatch.GetTimestamp();
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
long flushTimeout = FramebufferFlushTimer;
|
long flushTimeout = _framebufferFlushTimer;
|
||||||
|
|
||||||
long now = Stopwatch.GetTimestamp();
|
long now = Stopwatch.GetTimestamp();
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
long averageWait = (long)_syncWaitHistory.Average();
|
long averageWait = (long)_syncWaitHistory.Average();
|
||||||
|
|
||||||
if (_fastFlushMode ? averageWait < FastFlushExitThreshold : averageWait > FastFlushEnterThreshold)
|
if (_fastFlushMode ? averageWait < _fastFlushExitThreshold : averageWait > _fastFlushEnterThreshold)
|
||||||
{
|
{
|
||||||
_fastFlushMode = !_fastFlushMode;
|
_fastFlushMode = !_fastFlushMode;
|
||||||
Logger.Debug?.PrintMsg(LogClass.Gpu, $"Switched fast flush mode: ({_fastFlushMode})");
|
Logger.Debug?.PrintMsg(LogClass.Gpu, $"Switched fast flush mode: ({_fastFlushMode})");
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
class BackgroundResource : IDisposable
|
class BackgroundResource : IDisposable
|
||||||
{
|
{
|
||||||
private VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
private Device _device;
|
private Device _device;
|
||||||
|
|
||||||
private CommandBufferPool _pool;
|
private CommandBufferPool _pool;
|
||||||
|
@ -38,10 +38,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public PersistentFlushBuffer GetFlushBuffer()
|
public PersistentFlushBuffer GetFlushBuffer()
|
||||||
{
|
{
|
||||||
if (_flushBuffer == null)
|
_flushBuffer ??= new PersistentFlushBuffer(_gd);
|
||||||
{
|
|
||||||
_flushBuffer = new PersistentFlushBuffer(_gd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _flushBuffer;
|
return _flushBuffer;
|
||||||
}
|
}
|
||||||
|
@ -55,10 +52,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
class BackgroundResources : IDisposable
|
class BackgroundResources : IDisposable
|
||||||
{
|
{
|
||||||
private VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
private Device _device;
|
private Device _device;
|
||||||
|
|
||||||
private Dictionary<Thread, BackgroundResource> _resources;
|
private readonly Dictionary<Thread, BackgroundResource> _resources;
|
||||||
|
|
||||||
public BackgroundResources(VulkanRenderer gd, Device device)
|
public BackgroundResources(VulkanRenderer gd, Device device)
|
||||||
{
|
{
|
||||||
|
@ -89,8 +86,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
lock (_resources)
|
lock (_resources)
|
||||||
{
|
{
|
||||||
BackgroundResource resource;
|
if (!_resources.TryGetValue(thread, out BackgroundResource resource))
|
||||||
if (!_resources.TryGetValue(thread, out resource))
|
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,6 @@
|
||||||
HostMappedNoCache,
|
HostMappedNoCache,
|
||||||
HostMapped,
|
HostMapped,
|
||||||
DeviceLocal,
|
DeviceLocal,
|
||||||
DeviceLocalMapped
|
DeviceLocalMapped,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private MemoryAllocation _allocation;
|
private MemoryAllocation _allocation;
|
||||||
private Auto<DisposableBuffer> _buffer;
|
private Auto<DisposableBuffer> _buffer;
|
||||||
private Auto<MemoryAllocation> _allocationAuto;
|
private Auto<MemoryAllocation> _allocationAuto;
|
||||||
private bool _allocationImported;
|
private readonly bool _allocationImported;
|
||||||
private ulong _bufferHandle;
|
private ulong _bufferHandle;
|
||||||
|
|
||||||
private CacheByRange<BufferHolder> _cachedConvertedBuffers;
|
private CacheByRange<BufferHolder> _cachedConvertedBuffers;
|
||||||
|
@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private bool _lastAccessIsWrite;
|
private bool _lastAccessIsWrite;
|
||||||
|
|
||||||
private BufferAllocationType _baseType;
|
private readonly BufferAllocationType _baseType;
|
||||||
private BufferAllocationType _currentType;
|
private BufferAllocationType _currentType;
|
||||||
private bool _swapQueued;
|
private bool _swapQueued;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private int _flushTemp;
|
private int _flushTemp;
|
||||||
private int _lastFlushWrite = -1;
|
private int _lastFlushWrite = -1;
|
||||||
|
|
||||||
private ReaderWriterLock _flushLock;
|
private readonly ReaderWriterLock _flushLock;
|
||||||
private FenceHolder _flushFence;
|
private FenceHolder _flushFence;
|
||||||
private int _flushWaiting;
|
private int _flushWaiting;
|
||||||
|
|
||||||
|
@ -143,10 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (cbs == null)
|
cbs ??= _gd.CommandBufferPool.Rent();
|
||||||
{
|
|
||||||
cbs = _gd.CommandBufferPool.Rent();
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandBufferScoped cbsV = cbs.Value;
|
CommandBufferScoped cbsV = cbs.Value;
|
||||||
|
|
||||||
|
@ -184,18 +181,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_swapQueued = false;
|
_swapQueued = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void ConsiderBackingSwap()
|
private void ConsiderBackingSwap()
|
||||||
{
|
{
|
||||||
|
@ -251,13 +244,13 @@ 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()
|
var bufferViewCreateInfo = new BufferViewCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferViewCreateInfo,
|
SType = StructureType.BufferViewCreateInfo,
|
||||||
Buffer = new VkBuffer(_bufferHandle),
|
Buffer = new VkBuffer(_bufferHandle),
|
||||||
Format = format,
|
Format = format,
|
||||||
Offset = (uint)offset,
|
Offset = (uint)offset,
|
||||||
Range = (uint)size
|
Range = (uint)size,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.Api.CreateBufferView(_device, bufferViewCreateInfo, null, out var bufferView).ThrowOnError();
|
_gd.Api.CreateBufferView(_device, bufferViewCreateInfo, null, out var bufferView).ThrowOnError();
|
||||||
|
@ -288,11 +281,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (needsBarrier)
|
if (needsBarrier)
|
||||||
{
|
{
|
||||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
MemoryBarrier memoryBarrier = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryBarrier,
|
SType = StructureType.MemoryBarrier,
|
||||||
SrcAccessMask = DefaultAccessFlags,
|
SrcAccessMask = DefaultAccessFlags,
|
||||||
DstAccessMask = DefaultAccessFlags
|
DstAccessMask = DefaultAccessFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.Api.CmdPipelineBarrier(
|
_gd.Api.CmdPipelineBarrier(
|
||||||
|
@ -366,14 +359,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return Unsafe.As<ulong, BufferHandle>(ref handle);
|
return Unsafe.As<ulong, BufferHandle>(ref handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe IntPtr Map(int offset, int mappingSize)
|
public IntPtr Map(int offset, int mappingSize)
|
||||||
{
|
{
|
||||||
return _map;
|
return _map;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearFlushFence()
|
private void ClearFlushFence()
|
||||||
{
|
{
|
||||||
// Asusmes _flushLock is held as writer.
|
// Assumes _flushLock is held as writer.
|
||||||
|
|
||||||
if (_flushFence != null)
|
if (_flushFence != null)
|
||||||
{
|
{
|
||||||
|
@ -421,7 +414,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe PinnedSpan<byte> GetData(int offset, int size)
|
public PinnedSpan<byte> GetData(int offset, int size)
|
||||||
{
|
{
|
||||||
_flushLock.AcquireReaderLock(Timeout.Infinite);
|
_flushLock.AcquireReaderLock(Timeout.Infinite);
|
||||||
|
|
||||||
|
@ -447,8 +440,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount);
|
return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
BackgroundResource resource = _gd.BackgroundResources.Get();
|
BackgroundResource resource = _gd.BackgroundResources.Get();
|
||||||
|
|
||||||
if (_gd.CommandBufferPool.OwnedByCurrentThread)
|
if (_gd.CommandBufferPool.OwnedByCurrentThread)
|
||||||
|
@ -467,7 +459,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
|
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
|
||||||
return PinnedSpan<byte>.UnsafeFromSpan(result);
|
return PinnedSpan<byte>.UnsafeFromSpan(result);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe Span<byte> GetDataStorage(int offset, int size)
|
public unsafe Span<byte> GetDataStorage(int offset, int size)
|
||||||
{
|
{
|
||||||
|
@ -503,7 +494,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
WaitForFences(offset, dataSize);
|
WaitForFences(offset, dataSize);
|
||||||
|
|
||||||
data.Slice(0, dataSize).CopyTo(new Span<byte>((void*)(_map + offset), dataSize));
|
data[..dataSize].CopyTo(new Span<byte>((void*)(_map + offset), dataSize));
|
||||||
|
|
||||||
SignalWrite(offset, dataSize);
|
SignalWrite(offset, dataSize);
|
||||||
|
|
||||||
|
@ -542,7 +533,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (_map != IntPtr.Zero)
|
if (_map != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
data.Slice(0, dataSize).CopyTo(new Span<byte>((void*)(_map + offset), dataSize));
|
data[..dataSize].CopyTo(new Span<byte>((void*)(_map + offset), dataSize));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -657,7 +648,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
int offset,
|
int offset,
|
||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
BufferMemoryBarrier memoryBarrier = new BufferMemoryBarrier()
|
BufferMemoryBarrier memoryBarrier = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferMemoryBarrier,
|
SType = StructureType.BufferMemoryBarrier,
|
||||||
SrcAccessMask = srcAccessMask,
|
SrcAccessMask = srcAccessMask,
|
||||||
|
@ -666,7 +657,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
Buffer = buffer,
|
Buffer = buffer,
|
||||||
Offset = (ulong)offset,
|
Offset = (ulong)offset,
|
||||||
Size = (ulong)size
|
Size = (ulong)size,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CmdPipelineBarrier(
|
gd.Api.CmdPipelineBarrier(
|
||||||
|
|
|
@ -73,12 +73,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferCreateInfo = new BufferCreateInfo()
|
var bufferCreateInfo = new BufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferCreateInfo,
|
SType = StructureType.BufferCreateInfo,
|
||||||
Size = (ulong)size,
|
Size = (ulong)size,
|
||||||
Usage = usage,
|
Usage = usage,
|
||||||
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 var buffer).ThrowOnError();
|
||||||
|
@ -134,12 +134,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferCreateInfo = new BufferCreateInfo()
|
var bufferCreateInfo = new BufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferCreateInfo,
|
SType = StructureType.BufferCreateInfo,
|
||||||
Size = (ulong)Environment.SystemPageSize,
|
Size = (ulong)Environment.SystemPageSize,
|
||||||
Usage = usage,
|
Usage = usage,
|
||||||
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 var buffer).ThrowOnError();
|
||||||
|
@ -169,12 +169,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var bufferCreateInfo = new BufferCreateInfo()
|
var bufferCreateInfo = new BufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.BufferCreateInfo,
|
SType = StructureType.BufferCreateInfo,
|
||||||
Size = (ulong)size,
|
Size = (ulong)size,
|
||||||
Usage = usage,
|
Usage = usage,
|
||||||
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 var buffer).ThrowOnError();
|
||||||
|
@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
BufferAllocationType.HostMapped => DefaultBufferMemoryFlags,
|
BufferAllocationType.HostMapped => DefaultBufferMemoryFlags,
|
||||||
BufferAllocationType.DeviceLocal => DeviceLocalBufferMemoryFlags,
|
BufferAllocationType.DeviceLocal => DeviceLocalBufferMemoryFlags,
|
||||||
BufferAllocationType.DeviceLocalMapped => DeviceLocalMappedBufferMemoryFlags,
|
BufferAllocationType.DeviceLocalMapped => DeviceLocalMappedBufferMemoryFlags,
|
||||||
_ => DefaultBufferMemoryFlags
|
_ => DefaultBufferMemoryFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
// If an allocation with this memory type fails, fall back to the previous one.
|
// If an allocation with this memory type fails, fall back to the previous one.
|
||||||
|
@ -216,7 +216,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return (buffer, allocation, type);
|
return (buffer, allocation, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe BufferHolder Create(
|
public BufferHolder Create(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
int size,
|
int size,
|
||||||
bool forConditionalRendering = false,
|
bool forConditionalRendering = false,
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
struct BufferState : IDisposable
|
struct BufferState : IDisposable
|
||||||
{
|
{
|
||||||
public static BufferState Null => new BufferState(null, 0, 0);
|
public static BufferState Null => new(null, 0, 0);
|
||||||
|
|
||||||
private readonly int _offset;
|
private readonly int _offset;
|
||||||
private readonly int _size;
|
private readonly int _size;
|
||||||
|
@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
buffer?.IncrementReferenceCount();
|
buffer?.IncrementReferenceCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BindTransformFeedbackBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding)
|
public readonly void BindTransformFeedbackBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding)
|
||||||
{
|
{
|
||||||
if (_buffer != null)
|
if (_buffer != null)
|
||||||
{
|
{
|
||||||
|
@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
_buffer?.DecrementReferenceCount();
|
_buffer?.DecrementReferenceCount();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
{
|
{
|
||||||
internal class BufferUsageBitmap
|
internal class BufferUsageBitmap
|
||||||
{
|
{
|
||||||
private BitMap _bitmap;
|
private readonly BitMap _bitmap;
|
||||||
private int _size;
|
private readonly int _size;
|
||||||
private int _granularity;
|
private readonly int _granularity;
|
||||||
private int _bits;
|
private readonly int _bits;
|
||||||
|
|
||||||
private int _intsPerCb;
|
private readonly int _intsPerCb;
|
||||||
private int _bitsPerCb;
|
private readonly int _bitsPerCb;
|
||||||
|
|
||||||
public BufferUsageBitmap(int size, int granularity)
|
public BufferUsageBitmap(int size, int granularity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_buffer = null;
|
_buffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool KeyEqual(ICacheKey other)
|
public readonly bool KeyEqual(ICacheKey other)
|
||||||
{
|
{
|
||||||
return other is I8ToI16CacheKey;
|
return other is I8ToI16CacheKey;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
_gd.PipelineInternal.DirtyIndexBuffer(_buffer);
|
_gd.PipelineInternal.DirtyIndexBuffer(_buffer);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_buffer = null;
|
_buffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool KeyEqual(ICacheKey other)
|
public readonly bool KeyEqual(ICacheKey other)
|
||||||
{
|
{
|
||||||
return other is AlignedVertexBufferCacheKey entry &&
|
return other is AlignedVertexBufferCacheKey entry &&
|
||||||
entry._stride == _stride &&
|
entry._stride == _stride &&
|
||||||
|
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
_gd.PipelineInternal.DirtyVertexBuffer(_buffer);
|
_gd.PipelineInternal.DirtyVertexBuffer(_buffer);
|
||||||
}
|
}
|
||||||
|
@ -73,8 +73,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
struct TopologyConversionCacheKey : ICacheKey
|
struct TopologyConversionCacheKey : ICacheKey
|
||||||
{
|
{
|
||||||
private IndexBufferPattern _pattern;
|
private readonly IndexBufferPattern _pattern;
|
||||||
private int _indexSize;
|
private readonly int _indexSize;
|
||||||
|
|
||||||
// Used to notify the pipeline that bindings have invalidated on dispose.
|
// Used to notify the pipeline that bindings have invalidated on dispose.
|
||||||
private readonly VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
|
@ -88,7 +88,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_buffer = null;
|
_buffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool KeyEqual(ICacheKey other)
|
public readonly bool KeyEqual(ICacheKey other)
|
||||||
{
|
{
|
||||||
return other is TopologyConversionCacheKey entry &&
|
return other is TopologyConversionCacheKey entry &&
|
||||||
entry._pattern == _pattern &&
|
entry._pattern == _pattern &&
|
||||||
|
@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
_gd.PipelineInternal.DirtyIndexBuffer(_buffer);
|
_gd.PipelineInternal.DirtyIndexBuffer(_buffer);
|
||||||
}
|
}
|
||||||
|
@ -147,9 +147,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IndirectDataCacheKey : ICacheKey
|
readonly struct IndirectDataCacheKey : ICacheKey
|
||||||
{
|
{
|
||||||
private IndexBufferPattern _pattern;
|
private readonly IndexBufferPattern _pattern;
|
||||||
|
|
||||||
public IndirectDataCacheKey(IndexBufferPattern pattern)
|
public IndirectDataCacheKey(IndexBufferPattern pattern)
|
||||||
{
|
{
|
||||||
|
@ -168,12 +168,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
struct DrawCountCacheKey : ICacheKey
|
struct DrawCountCacheKey : ICacheKey
|
||||||
{
|
{
|
||||||
public bool KeyEqual(ICacheKey other)
|
public readonly bool KeyEqual(ICacheKey other)
|
||||||
{
|
{
|
||||||
return other is DrawCountCacheKey;
|
return other is DrawCountCacheKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DependencyList = null;
|
DependencyList = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvalidateDependencies()
|
public readonly void InvalidateDependencies()
|
||||||
{
|
{
|
||||||
if (DependencyList != null)
|
if (DependencyList != null)
|
||||||
{
|
{
|
||||||
|
@ -317,7 +317,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRange(int offset, int size)
|
public readonly void ClearRange(int offset, int size)
|
||||||
{
|
{
|
||||||
if (_ranges != null && _ranges.Count > 0)
|
if (_ranges != null && _ranges.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -356,15 +356,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private List<Entry> GetEntries(int offset, int size)
|
private List<Entry> GetEntries(int offset, int size)
|
||||||
{
|
{
|
||||||
if (_ranges == null)
|
_ranges ??= new Dictionary<ulong, List<Entry>>();
|
||||||
{
|
|
||||||
_ranges = new Dictionary<ulong, List<Entry>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
ulong key = PackRange(offset, size);
|
ulong key = PackRange(offset, size);
|
||||||
|
|
||||||
List<Entry> value;
|
if (!_ranges.TryGetValue(key, out List<Entry> value))
|
||||||
if (!_ranges.TryGetValue(key, out value))
|
|
||||||
{
|
{
|
||||||
value = new List<Entry>();
|
value = new List<Entry>();
|
||||||
_ranges.Add(key, value);
|
_ranges.Add(key, value);
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Thread = System.Threading.Thread;
|
using System.Threading;
|
||||||
|
using Semaphore = Silk.NET.Vulkan.Semaphore;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -10,8 +11,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
public const int MaxCommandBuffers = 16;
|
public const int MaxCommandBuffers = 16;
|
||||||
|
|
||||||
private int _totalCommandBuffers;
|
private readonly int _totalCommandBuffers;
|
||||||
private int _totalCommandBuffersMask;
|
private readonly int _totalCommandBuffersMask;
|
||||||
|
|
||||||
private readonly Vk _api;
|
private readonly Vk _api;
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
|
@ -36,12 +37,12 @@ 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()
|
var allocateInfo = new CommandBufferAllocateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.CommandBufferAllocateInfo,
|
SType = StructureType.CommandBufferAllocateInfo,
|
||||||
CommandBufferCount = 1,
|
CommandBufferCount = 1,
|
||||||
CommandPool = pool,
|
CommandPool = pool,
|
||||||
Level = CommandBufferLevel.Primary
|
Level = CommandBufferLevel.Primary,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.AllocateCommandBuffers(device, allocateInfo, out CommandBuffer);
|
api.AllocateCommandBuffers(device, allocateInfo, out CommandBuffer);
|
||||||
|
@ -67,12 +68,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_queueLock = queueLock;
|
_queueLock = queueLock;
|
||||||
_owner = Thread.CurrentThread;
|
_owner = Thread.CurrentThread;
|
||||||
|
|
||||||
var commandPoolCreateInfo = new CommandPoolCreateInfo()
|
var commandPoolCreateInfo = new CommandPoolCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.CommandPoolCreateInfo,
|
SType = StructureType.CommandPoolCreateInfo,
|
||||||
QueueFamilyIndex = queueFamilyIndex,
|
QueueFamilyIndex = queueFamilyIndex,
|
||||||
Flags = CommandPoolCreateFlags.TransientBit |
|
Flags = CommandPoolCreateFlags.TransientBit |
|
||||||
CommandPoolCreateFlags.ResetCommandBufferBit
|
CommandPoolCreateFlags.ResetCommandBufferBit,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CreateCommandPool(device, commandPoolCreateInfo, null, out _pool).ThrowOnError();
|
api.CreateCommandPool(device, commandPoolCreateInfo, null, out _pool).ThrowOnError();
|
||||||
|
@ -243,9 +244,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_inUseCount++;
|
_inUseCount++;
|
||||||
|
|
||||||
var commandBufferBeginInfo = new CommandBufferBeginInfo()
|
var commandBufferBeginInfo = new CommandBufferBeginInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.CommandBufferBeginInfo
|
SType = StructureType.CommandBufferBeginInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
_api.BeginCommandBuffer(entry.CommandBuffer, commandBufferBeginInfo).ThrowOnError();
|
_api.BeginCommandBuffer(entry.CommandBuffer, commandBufferBeginInfo).ThrowOnError();
|
||||||
|
@ -291,7 +292,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
fixed (PipelineStageFlags* pWaitDstStageMask = waitDstStageMask)
|
fixed (PipelineStageFlags* pWaitDstStageMask = waitDstStageMask)
|
||||||
{
|
{
|
||||||
SubmitInfo sInfo = new SubmitInfo()
|
SubmitInfo sInfo = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.SubmitInfo,
|
SType = StructureType.SubmitInfo,
|
||||||
WaitSemaphoreCount = waitSemaphores != null ? (uint)waitSemaphores.Length : 0,
|
WaitSemaphoreCount = waitSemaphores != null ? (uint)waitSemaphores.Length : 0,
|
||||||
|
@ -300,7 +301,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
CommandBufferCount = 1,
|
CommandBufferCount = 1,
|
||||||
PCommandBuffers = &commandBuffer,
|
PCommandBuffers = &commandBuffer,
|
||||||
SignalSemaphoreCount = signalSemaphores != null ? (uint)signalSemaphores.Length : 0,
|
SignalSemaphoreCount = signalSemaphores != null ? (uint)signalSemaphores.Length : 0,
|
||||||
PSignalSemaphores = pSignalSemaphores
|
PSignalSemaphores = pSignalSemaphores,
|
||||||
};
|
};
|
||||||
|
|
||||||
lock (_queueLock)
|
lock (_queueLock)
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
private DescriptorSetManager.DescriptorPoolHolder _holder;
|
private DescriptorSetManager.DescriptorPoolHolder _holder;
|
||||||
private readonly DescriptorSet[] _descriptorSets;
|
private readonly DescriptorSet[] _descriptorSets;
|
||||||
public int SetsCount => _descriptorSets.Length;
|
public readonly int SetsCount => _descriptorSets.Length;
|
||||||
|
|
||||||
public DescriptorSetCollection(DescriptorSetManager.DescriptorPoolHolder holder, DescriptorSet[] descriptorSets)
|
public DescriptorSetCollection(DescriptorSetManager.DescriptorPoolHolder holder, DescriptorSet[] descriptorSets)
|
||||||
{
|
{
|
||||||
|
@ -20,10 +20,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[count];
|
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[count];
|
||||||
|
|
||||||
infos.Fill(new DescriptorBufferInfo()
|
infos.Fill(new DescriptorBufferInfo
|
||||||
{
|
{
|
||||||
Buffer = dummyBuffer,
|
Buffer = dummyBuffer,
|
||||||
Range = Vk.WholeSize
|
Range = Vk.WholeSize,
|
||||||
});
|
});
|
||||||
|
|
||||||
UpdateBuffers(setIndex, baseBinding, infos, type);
|
UpdateBuffers(setIndex, baseBinding, infos, type);
|
||||||
|
@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstBinding = (uint)bindingIndex,
|
DstBinding = (uint)bindingIndex,
|
||||||
DescriptorType = type,
|
DescriptorType = type,
|
||||||
DescriptorCount = 1,
|
DescriptorCount = 1,
|
||||||
PBufferInfo = &bufferInfo
|
PBufferInfo = &bufferInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||||
|
@ -63,7 +63,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstBinding = (uint)baseBinding,
|
DstBinding = (uint)baseBinding,
|
||||||
DescriptorType = type,
|
DescriptorType = type,
|
||||||
DescriptorCount = (uint)bufferInfo.Length,
|
DescriptorCount = (uint)bufferInfo.Length,
|
||||||
PBufferInfo = pBufferInfo
|
PBufferInfo = pBufferInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||||
|
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstBinding = (uint)bindingIndex,
|
DstBinding = (uint)bindingIndex,
|
||||||
DescriptorType = type,
|
DescriptorType = type,
|
||||||
DescriptorCount = 1,
|
DescriptorCount = 1,
|
||||||
PImageInfo = &imageInfo
|
PImageInfo = &imageInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||||
|
@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstBinding = (uint)baseBinding,
|
DstBinding = (uint)baseBinding,
|
||||||
DescriptorType = type,
|
DescriptorType = type,
|
||||||
DescriptorCount = (uint)imageInfo.Length,
|
DescriptorCount = (uint)imageInfo.Length,
|
||||||
PImageInfo = pImageInfo
|
PImageInfo = pImageInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||||
|
@ -141,7 +141,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstBinding = (uint)(baseBinding + i),
|
DstBinding = (uint)(baseBinding + i),
|
||||||
DescriptorType = DescriptorType.CombinedImageSampler,
|
DescriptorType = DescriptorType.CombinedImageSampler,
|
||||||
DescriptorCount = (uint)count,
|
DescriptorCount = (uint)count,
|
||||||
PImageInfo = pImageInfo
|
PImageInfo = pImageInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||||
|
@ -163,7 +163,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstBinding = (uint)bindingIndex,
|
DstBinding = (uint)bindingIndex,
|
||||||
DescriptorType = type,
|
DescriptorType = type,
|
||||||
DescriptorCount = 1,
|
DescriptorCount = 1,
|
||||||
PTexelBufferView = &texelBufferView
|
PTexelBufferView = &texelBufferView,
|
||||||
};
|
};
|
||||||
|
|
||||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||||
|
@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstBinding = (uint)baseBinding + i,
|
DstBinding = (uint)baseBinding + i,
|
||||||
DescriptorType = type,
|
DescriptorType = type,
|
||||||
DescriptorCount = count,
|
DescriptorCount = count,
|
||||||
PTexelBufferView = pTexelBufferView + i
|
PTexelBufferView = pTexelBufferView + i,
|
||||||
};
|
};
|
||||||
|
|
||||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||||
|
@ -208,7 +208,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DescriptorSet[] GetSets()
|
public readonly DescriptorSet[] GetSets()
|
||||||
{
|
{
|
||||||
return _descriptorSets;
|
return _descriptorSets;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Api = api;
|
Api = api;
|
||||||
Device = device;
|
Device = device;
|
||||||
|
|
||||||
var poolSizes = new DescriptorPoolSize[]
|
var poolSizes = new[]
|
||||||
{
|
{
|
||||||
new DescriptorPoolSize(DescriptorType.UniformBuffer, (1 + Constants.MaxUniformBufferBindings) * DescriptorPoolMultiplier),
|
new DescriptorPoolSize(DescriptorType.UniformBuffer, (1 + Constants.MaxUniformBufferBindings) * DescriptorPoolMultiplier),
|
||||||
new DescriptorPoolSize(DescriptorType.StorageBuffer, Constants.MaxStorageBufferBindings * DescriptorPoolMultiplier),
|
new DescriptorPoolSize(DescriptorType.StorageBuffer, Constants.MaxStorageBufferBindings * DescriptorPoolMultiplier),
|
||||||
new DescriptorPoolSize(DescriptorType.CombinedImageSampler, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
|
new DescriptorPoolSize(DescriptorType.CombinedImageSampler, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
|
||||||
new DescriptorPoolSize(DescriptorType.StorageImage, Constants.MaxImageBindings * DescriptorPoolMultiplier),
|
new DescriptorPoolSize(DescriptorType.StorageImage, Constants.MaxImageBindings * DescriptorPoolMultiplier),
|
||||||
new DescriptorPoolSize(DescriptorType.UniformTexelBuffer, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
|
new DescriptorPoolSize(DescriptorType.UniformTexelBuffer, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
|
||||||
new DescriptorPoolSize(DescriptorType.StorageTexelBuffer, Constants.MaxImageBindings * DescriptorPoolMultiplier)
|
new DescriptorPoolSize(DescriptorType.StorageTexelBuffer, Constants.MaxImageBindings * DescriptorPoolMultiplier),
|
||||||
};
|
};
|
||||||
|
|
||||||
uint maxSets = (uint)poolSizes.Length * DescriptorPoolMultiplier;
|
uint maxSets = (uint)poolSizes.Length * DescriptorPoolMultiplier;
|
||||||
|
@ -40,19 +40,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
fixed (DescriptorPoolSize* pPoolsSize = poolSizes)
|
fixed (DescriptorPoolSize* pPoolsSize = poolSizes)
|
||||||
{
|
{
|
||||||
var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo()
|
var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DescriptorPoolCreateInfo,
|
SType = StructureType.DescriptorPoolCreateInfo,
|
||||||
MaxSets = maxSets,
|
MaxSets = maxSets,
|
||||||
PoolSizeCount = (uint)poolSizes.Length,
|
PoolSizeCount = (uint)poolSizes.Length,
|
||||||
PPoolSizes = pPoolsSize
|
PPoolSizes = pPoolsSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
Api.CreateDescriptorPool(device, descriptorPoolCreateInfo, null, out _pool).ThrowOnError();
|
Api.CreateDescriptorPool(device, descriptorPoolCreateInfo, null, out _pool).ThrowOnError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe DescriptorSetCollection AllocateDescriptorSets(ReadOnlySpan<DescriptorSetLayout> layouts)
|
public DescriptorSetCollection AllocateDescriptorSets(ReadOnlySpan<DescriptorSetLayout> layouts)
|
||||||
{
|
{
|
||||||
TryAllocateDescriptorSets(layouts, isTry: false, out var dsc);
|
TryAllocateDescriptorSets(layouts, isTry: false, out var dsc);
|
||||||
return dsc;
|
return dsc;
|
||||||
|
@ -73,12 +73,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
fixed (DescriptorSetLayout* pLayouts = layouts)
|
fixed (DescriptorSetLayout* pLayouts = layouts)
|
||||||
{
|
{
|
||||||
var descriptorSetAllocateInfo = new DescriptorSetAllocateInfo()
|
var descriptorSetAllocateInfo = new DescriptorSetAllocateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DescriptorSetAllocateInfo,
|
SType = StructureType.DescriptorSetAllocateInfo,
|
||||||
DescriptorPool = _pool,
|
DescriptorPool = _pool,
|
||||||
DescriptorSetCount = (uint)layouts.Length,
|
DescriptorSetCount = (uint)layouts.Length,
|
||||||
PSetLayouts = pLayouts
|
PSetLayouts = pLayouts,
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = Api.AllocateDescriptorSets(Device, &descriptorSetAllocateInfo, pDescriptorSets);
|
var result = Api.AllocateDescriptorSets(Device, &descriptorSetAllocateInfo, pDescriptorSets);
|
||||||
|
@ -142,6 +142,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,16 +186,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
protected virtual void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
|
||||||
unsafe
|
|
||||||
{
|
{
|
||||||
_currentPool?.Dispose();
|
_currentPool?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Numerics;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
|
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||||
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
|
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -14,25 +17,25 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private ShaderCollection _program;
|
private ShaderCollection _program;
|
||||||
|
|
||||||
private Auto<DisposableBuffer>[] _uniformBufferRefs;
|
private readonly Auto<DisposableBuffer>[] _uniformBufferRefs;
|
||||||
private Auto<DisposableBuffer>[] _storageBufferRefs;
|
private readonly Auto<DisposableBuffer>[] _storageBufferRefs;
|
||||||
private Auto<DisposableImageView>[] _textureRefs;
|
private readonly Auto<DisposableImageView>[] _textureRefs;
|
||||||
private Auto<DisposableSampler>[] _samplerRefs;
|
private readonly Auto<DisposableSampler>[] _samplerRefs;
|
||||||
private Auto<DisposableImageView>[] _imageRefs;
|
private readonly Auto<DisposableImageView>[] _imageRefs;
|
||||||
private TextureBuffer[] _bufferTextureRefs;
|
private readonly TextureBuffer[] _bufferTextureRefs;
|
||||||
private TextureBuffer[] _bufferImageRefs;
|
private readonly TextureBuffer[] _bufferImageRefs;
|
||||||
private GAL.Format[] _bufferImageFormats;
|
private readonly Format[] _bufferImageFormats;
|
||||||
|
|
||||||
private DescriptorBufferInfo[] _uniformBuffers;
|
private readonly DescriptorBufferInfo[] _uniformBuffers;
|
||||||
private DescriptorBufferInfo[] _storageBuffers;
|
private readonly DescriptorBufferInfo[] _storageBuffers;
|
||||||
private DescriptorImageInfo[] _textures;
|
private readonly DescriptorImageInfo[] _textures;
|
||||||
private DescriptorImageInfo[] _images;
|
private readonly DescriptorImageInfo[] _images;
|
||||||
private BufferView[] _bufferTextures;
|
private readonly BufferView[] _bufferTextures;
|
||||||
private BufferView[] _bufferImages;
|
private readonly BufferView[] _bufferImages;
|
||||||
|
|
||||||
private bool[] _uniformSet;
|
private readonly bool[] _uniformSet;
|
||||||
private bool[] _storageSet;
|
private readonly bool[] _storageSet;
|
||||||
private Silk.NET.Vulkan.Buffer _cachedSupportBuffer;
|
private Buffer _cachedSupportBuffer;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum DirtyFlags
|
private enum DirtyFlags
|
||||||
|
@ -42,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Storage = 1 << 1,
|
Storage = 1 << 1,
|
||||||
Texture = 1 << 2,
|
Texture = 1 << 2,
|
||||||
Image = 1 << 3,
|
Image = 1 << 3,
|
||||||
All = Uniform | Storage | Texture | Image
|
All = Uniform | Storage | Texture | Image,
|
||||||
}
|
}
|
||||||
|
|
||||||
private DirtyFlags _dirty;
|
private DirtyFlags _dirty;
|
||||||
|
@ -66,7 +69,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_imageRefs = new Auto<DisposableImageView>[Constants.MaxImageBindings * 2];
|
_imageRefs = new Auto<DisposableImageView>[Constants.MaxImageBindings * 2];
|
||||||
_bufferTextureRefs = new TextureBuffer[Constants.MaxTextureBindings * 2];
|
_bufferTextureRefs = new TextureBuffer[Constants.MaxTextureBindings * 2];
|
||||||
_bufferImageRefs = new TextureBuffer[Constants.MaxImageBindings * 2];
|
_bufferImageRefs = new TextureBuffer[Constants.MaxImageBindings * 2];
|
||||||
_bufferImageFormats = new GAL.Format[Constants.MaxImageBindings * 2];
|
_bufferImageFormats = new Format[Constants.MaxImageBindings * 2];
|
||||||
|
|
||||||
_uniformBuffers = new DescriptorBufferInfo[Constants.MaxUniformBufferBindings];
|
_uniformBuffers = new DescriptorBufferInfo[Constants.MaxUniformBufferBindings];
|
||||||
_storageBuffers = new DescriptorBufferInfo[Constants.MaxStorageBufferBindings];
|
_storageBuffers = new DescriptorBufferInfo[Constants.MaxStorageBufferBindings];
|
||||||
|
@ -75,9 +78,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_bufferTextures = new BufferView[Constants.MaxTexturesPerStage];
|
_bufferTextures = new BufferView[Constants.MaxTexturesPerStage];
|
||||||
_bufferImages = new BufferView[Constants.MaxImagesPerStage];
|
_bufferImages = new BufferView[Constants.MaxImagesPerStage];
|
||||||
|
|
||||||
var initialImageInfo = new DescriptorImageInfo()
|
var initialImageInfo = new DescriptorImageInfo
|
||||||
{
|
{
|
||||||
ImageLayout = ImageLayout.General
|
ImageLayout = ImageLayout.General,
|
||||||
};
|
};
|
||||||
|
|
||||||
_textures.AsSpan().Fill(initialImageInfo);
|
_textures.AsSpan().Fill(initialImageInfo);
|
||||||
|
@ -106,7 +109,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
4,
|
4,
|
||||||
GAL.Format.R8G8B8A8Unorm,
|
Format.R8G8B8A8Unorm,
|
||||||
DepthStencilMode.Depth,
|
DepthStencilMode.Depth,
|
||||||
Target.Texture2D,
|
Target.Texture2D,
|
||||||
SwizzleComponent.Red,
|
SwizzleComponent.Red,
|
||||||
|
@ -114,7 +117,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SwizzleComponent.Blue,
|
SwizzleComponent.Blue,
|
||||||
SwizzleComponent.Alpha), 1f);
|
SwizzleComponent.Alpha), 1f);
|
||||||
|
|
||||||
_dummySampler = (SamplerHolder)gd.CreateSampler(new GAL.SamplerCreateInfo(
|
_dummySampler = (SamplerHolder)gd.CreateSampler(new SamplerCreateInfo(
|
||||||
MinFilter.Nearest,
|
MinFilter.Nearest,
|
||||||
MagFilter.Nearest,
|
MagFilter.Nearest,
|
||||||
false,
|
false,
|
||||||
|
@ -122,7 +125,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
AddressMode.Repeat,
|
AddressMode.Repeat,
|
||||||
AddressMode.Repeat,
|
AddressMode.Repeat,
|
||||||
CompareMode.None,
|
CompareMode.None,
|
||||||
GAL.CompareOp.Always,
|
CompareOp.Always,
|
||||||
new ColorF(0, 0, 0, 0),
|
new ColorF(0, 0, 0, 0),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
|
@ -142,7 +145,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_dirty = DirtyFlags.All;
|
_dirty = DirtyFlags.All;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetImage(int binding, ITexture image, GAL.Format imageFormat)
|
public void SetImage(int binding, ITexture image, Format imageFormat)
|
||||||
{
|
{
|
||||||
if (image is TextureBuffer imageBuffer)
|
if (image is TextureBuffer imageBuffer)
|
||||||
{
|
{
|
||||||
|
@ -181,10 +184,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false, isSSBO: true);
|
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false, isSSBO: true);
|
||||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
||||||
|
|
||||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
DescriptorBufferInfo info = new()
|
||||||
{
|
{
|
||||||
Offset = (ulong)buffer.Offset,
|
Offset = (ulong)buffer.Offset,
|
||||||
Range = (ulong)buffer.Size
|
Range = (ulong)buffer.Size,
|
||||||
};
|
};
|
||||||
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
||||||
|
|
||||||
|
@ -209,10 +212,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
||||||
|
|
||||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
DescriptorBufferInfo info = new()
|
||||||
{
|
{
|
||||||
Offset = 0,
|
Offset = 0,
|
||||||
Range = Vk.WholeSize
|
Range = Vk.WholeSize,
|
||||||
};
|
};
|
||||||
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
||||||
|
|
||||||
|
@ -289,10 +292,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
|
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
|
||||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _uniformBufferRefs[index];
|
ref Auto<DisposableBuffer> currentVkBuffer = ref _uniformBufferRefs[index];
|
||||||
|
|
||||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
DescriptorBufferInfo info = new()
|
||||||
{
|
{
|
||||||
Offset = (ulong)buffer.Offset,
|
Offset = (ulong)buffer.Offset,
|
||||||
Range = (ulong)buffer.Size
|
Range = (ulong)buffer.Size,
|
||||||
};
|
};
|
||||||
ref DescriptorBufferInfo currentInfo = ref _uniformBuffers[index];
|
ref DescriptorBufferInfo currentInfo = ref _uniformBuffers[index];
|
||||||
|
|
||||||
|
@ -400,11 +403,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_uniformSet[0] = true;
|
_uniformSet[0] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uniformBuffer[0] = new DescriptorBufferInfo()
|
uniformBuffer[0] = new DescriptorBufferInfo
|
||||||
{
|
{
|
||||||
Offset = 0,
|
Offset = 0,
|
||||||
Range = (ulong)SupportBuffer.RequiredSize,
|
Range = (ulong)SupportBuffer.RequiredSize,
|
||||||
Buffer = _cachedSupportBuffer
|
Buffer = _cachedSupportBuffer,
|
||||||
};
|
};
|
||||||
|
|
||||||
dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
||||||
|
@ -474,7 +477,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dsc.UpdateImages(0, binding, textures.Slice(0, count), DescriptorType.CombinedImageSampler);
|
dsc.UpdateImages(0, binding, textures[..count], DescriptorType.CombinedImageSampler);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -485,7 +488,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
bufferTextures[i] = _bufferTextureRefs[binding + i]?.GetBufferView(cbs) ?? default;
|
bufferTextures[i] = _bufferTextureRefs[binding + i]?.GetBufferView(cbs) ?? default;
|
||||||
}
|
}
|
||||||
|
|
||||||
dsc.UpdateBufferImages(0, binding, bufferTextures.Slice(0, count), DescriptorType.UniformTexelBuffer);
|
dsc.UpdateBufferImages(0, binding, bufferTextures[..count], DescriptorType.UniformTexelBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (setIndex == PipelineBase.ImageSetIndex)
|
else if (setIndex == PipelineBase.ImageSetIndex)
|
||||||
|
@ -499,7 +502,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
images[i].ImageView = _imageRefs[binding + i]?.Get(cbs).Value ?? default;
|
images[i].ImageView = _imageRefs[binding + i]?.Get(cbs).Value ?? default;
|
||||||
}
|
}
|
||||||
|
|
||||||
dsc.UpdateImages(0, binding, images.Slice(0, count), DescriptorType.StorageImage);
|
dsc.UpdateImages(0, binding, images[..count], DescriptorType.StorageImage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -510,7 +513,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
bufferImages[i] = _bufferImageRefs[binding + i]?.GetBufferView(cbs, _bufferImageFormats[binding + i]) ?? default;
|
bufferImages[i] = _bufferImageRefs[binding + i]?.GetBufferView(cbs, _bufferImageFormats[binding + i]) ?? default;
|
||||||
}
|
}
|
||||||
|
|
||||||
dsc.UpdateBufferImages(0, binding, bufferImages.Slice(0, count), DescriptorType.StorageTexelBuffer);
|
dsc.UpdateBufferImages(0, binding, bufferImages[..count], DescriptorType.StorageTexelBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -540,7 +543,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DstBinding = (uint)baseBinding,
|
DstBinding = (uint)baseBinding,
|
||||||
DescriptorType = type,
|
DescriptorType = type,
|
||||||
DescriptorCount = (uint)bufferInfo.Length,
|
DescriptorCount = (uint)bufferInfo.Length,
|
||||||
PBufferInfo = pBufferInfo
|
PBufferInfo = pBufferInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.PushDescriptorApi.CmdPushDescriptorSet(cbs.CommandBuffer, pbp, _program.PipelineLayout, 0, 1, &writeDescriptorSet);
|
_gd.PushDescriptorApi.CmdPushDescriptorSet(cbs.CommandBuffer, pbp, _program.PipelineLayout, 0, 1, &writeDescriptorSet);
|
||||||
|
@ -554,11 +557,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
||||||
|
|
||||||
uniformBuffer[0] = new DescriptorBufferInfo()
|
uniformBuffer[0] = new DescriptorBufferInfo
|
||||||
{
|
{
|
||||||
Offset = 0,
|
Offset = 0,
|
||||||
Range = (ulong)SupportBuffer.RequiredSize,
|
Range = (ulong)SupportBuffer.RequiredSize,
|
||||||
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value
|
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
_uniformSet[0] = true;
|
_uniformSet[0] = true;
|
||||||
|
@ -620,7 +623,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Array.Clear(_storageSet);
|
Array.Clear(_storageSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SwapBuffer(Auto<DisposableBuffer>[] list, Auto<DisposableBuffer> from, Auto<DisposableBuffer> to)
|
private static void SwapBuffer(Auto<DisposableBuffer>[] list, Auto<DisposableBuffer> from, Auto<DisposableBuffer> to)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < list.Length; i++)
|
for (int i = 0; i < list.Length; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -8,9 +9,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly Vk _api;
|
private readonly Vk _api;
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
|
|
||||||
public Silk.NET.Vulkan.Buffer Value { get; }
|
public Buffer Value { get; }
|
||||||
|
|
||||||
public DisposableBuffer(Vk api, Device device, Silk.NET.Vulkan.Buffer buffer)
|
public DisposableBuffer(Vk api, Device device, Buffer buffer)
|
||||||
{
|
{
|
||||||
_api = api;
|
_api = api;
|
||||||
_device = device;
|
_device = device;
|
||||||
|
|
|
@ -5,10 +5,12 @@ using Ryujinx.Graphics.Shader.Translation;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using Extent2D = Ryujinx.Graphics.GAL.Extents2D;
|
using Extent2D = Ryujinx.Graphics.GAL.Extents2D;
|
||||||
|
using Format = Silk.NET.Vulkan.Format;
|
||||||
|
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
{
|
{
|
||||||
internal partial class FsrScalingFilter : IScalingFilter
|
internal class FsrScalingFilter : IScalingFilter
|
||||||
{
|
{
|
||||||
private readonly VulkanRenderer _renderer;
|
private readonly VulkanRenderer _renderer;
|
||||||
private PipelineHelperShader _pipeline;
|
private PipelineHelperShader _pipeline;
|
||||||
|
@ -66,16 +68,16 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
||||||
|
|
||||||
_sampler = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
_sampler = _renderer.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||||
|
|
||||||
_scalingProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
_scalingProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(scalingShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
new ShaderSource(scalingShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, scalingResourceLayout);
|
}, scalingResourceLayout);
|
||||||
|
|
||||||
_sharpeningProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
_sharpeningProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(sharpeningShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
new ShaderSource(sharpeningShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, sharpeningResourceLayout);
|
}, sharpeningResourceLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
TextureView view,
|
TextureView view,
|
||||||
CommandBufferScoped cbs,
|
CommandBufferScoped cbs,
|
||||||
Auto<DisposableImageView> destinationTexture,
|
Auto<DisposableImageView> destinationTexture,
|
||||||
Silk.NET.Vulkan.Format format,
|
Format format,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
Extent2D source,
|
Extent2D source,
|
||||||
|
@ -136,7 +138,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
destination.Y1,
|
destination.Y1,
|
||||||
destination.Y2,
|
destination.Y2,
|
||||||
scaleX,
|
scaleX,
|
||||||
scaleY
|
scaleY,
|
||||||
};
|
};
|
||||||
|
|
||||||
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
||||||
|
|
|
@ -4,16 +4,17 @@ using Ryujinx.Graphics.Shader;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
{
|
{
|
||||||
internal partial class FxaaPostProcessingEffect : IPostProcessingEffect
|
internal class FxaaPostProcessingEffect : IPostProcessingEffect
|
||||||
{
|
{
|
||||||
private readonly VulkanRenderer _renderer;
|
private readonly VulkanRenderer _renderer;
|
||||||
private ISampler _samplerLinear;
|
private ISampler _samplerLinear;
|
||||||
private ShaderCollection _shaderProgram;
|
private ShaderCollection _shaderProgram;
|
||||||
|
|
||||||
private PipelineHelperShader _pipeline;
|
private readonly PipelineHelperShader _pipeline;
|
||||||
private TextureView _texture;
|
private TextureView _texture;
|
||||||
|
|
||||||
public FxaaPostProcessingEffect(VulkanRenderer renderer, Device device)
|
public FxaaPostProcessingEffect(VulkanRenderer renderer, Device device)
|
||||||
|
@ -43,11 +44,11 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
||||||
|
|
||||||
_samplerLinear = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
_samplerLinear = _renderer.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||||
|
|
||||||
_shaderProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
_shaderProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(shader, ShaderStage.Compute, TargetLanguage.Spirv)
|
new ShaderSource(shader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, resourceLayout);
|
}, resourceLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,12 @@ using Ryujinx.Graphics.Shader;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
|
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
{
|
{
|
||||||
internal partial class SmaaPostProcessingEffect : IPostProcessingEffect
|
internal class SmaaPostProcessingEffect : IPostProcessingEffect
|
||||||
{
|
{
|
||||||
public const int AreaWidth = 160;
|
public const int AreaWidth = 160;
|
||||||
public const int AreaHeight = 560;
|
public const int AreaHeight = 560;
|
||||||
|
@ -63,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
_searchTexture?.Dispose();
|
_searchTexture?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void RecreateShaders(int width, int height)
|
private void RecreateShaders(int width, int height)
|
||||||
{
|
{
|
||||||
_recreatePipelines = false;
|
_recreatePipelines = false;
|
||||||
|
|
||||||
|
@ -94,9 +96,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 3)
|
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 3)
|
||||||
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
||||||
|
|
||||||
_samplerLinear = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
_samplerLinear = _renderer.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||||
|
|
||||||
_specConstants = new SmaaConstants()
|
_specConstants = new SmaaConstants
|
||||||
{
|
{
|
||||||
Width = width,
|
Width = width,
|
||||||
Height = height,
|
Height = height,
|
||||||
|
@ -116,17 +118,17 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
|
|
||||||
_edgeProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
_edgeProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(edgeShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
new ShaderSource(edgeShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, edgeResourceLayout, new[] { specInfo });
|
}, edgeResourceLayout, new[] { specInfo });
|
||||||
|
|
||||||
_blendProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
_blendProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(blendShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
new ShaderSource(blendShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, blendResourceLayout, new[] { specInfo });
|
}, blendResourceLayout, new[] { specInfo });
|
||||||
|
|
||||||
_neighbourProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
_neighbourProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||||
{
|
{
|
||||||
new ShaderSource(neighbourShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
new ShaderSource(neighbourShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||||
}, neighbourResourceLayout, new[] { specInfo });
|
}, neighbourResourceLayout, new[] { specInfo });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +150,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
GAL.Format.R8G8Unorm,
|
Format.R8G8Unorm,
|
||||||
DepthStencilMode.Depth,
|
DepthStencilMode.Depth,
|
||||||
Target.Texture2D,
|
Target.Texture2D,
|
||||||
SwizzleComponent.Red,
|
SwizzleComponent.Red,
|
||||||
|
@ -164,7 +166,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
GAL.Format.R8Unorm,
|
Format.R8Unorm,
|
||||||
DepthStencilMode.Depth,
|
DepthStencilMode.Depth,
|
||||||
Target.Texture2D,
|
Target.Texture2D,
|
||||||
SwizzleComponent.Red,
|
SwizzleComponent.Red,
|
||||||
|
|
|
@ -3,6 +3,14 @@ using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
using BlendFactor = Silk.NET.Vulkan.BlendFactor;
|
||||||
|
using BlendOp = Silk.NET.Vulkan.BlendOp;
|
||||||
|
using CompareOp = Silk.NET.Vulkan.CompareOp;
|
||||||
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
|
using FrontFace = Silk.NET.Vulkan.FrontFace;
|
||||||
|
using IndexType = Silk.NET.Vulkan.IndexType;
|
||||||
|
using PrimitiveTopology = Silk.NET.Vulkan.PrimitiveTopology;
|
||||||
|
using StencilOp = Silk.NET.Vulkan.StencilOp;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -18,7 +26,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ShaderStage.TessellationEvaluation => ShaderStageFlags.TessellationEvaluationBit,
|
ShaderStage.TessellationEvaluation => ShaderStageFlags.TessellationEvaluationBit,
|
||||||
ShaderStage.Fragment => ShaderStageFlags.FragmentBit,
|
ShaderStage.Fragment => ShaderStageFlags.FragmentBit,
|
||||||
ShaderStage.Compute => ShaderStageFlags.ComputeBit,
|
ShaderStage.Compute => ShaderStageFlags.ComputeBit,
|
||||||
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (ShaderStageFlags)0)
|
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (ShaderStageFlags)0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +40,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ShaderStage.TessellationEvaluation => PipelineStageFlags.TessellationEvaluationShaderBit,
|
ShaderStage.TessellationEvaluation => PipelineStageFlags.TessellationEvaluationShaderBit,
|
||||||
ShaderStage.Fragment => PipelineStageFlags.FragmentShaderBit,
|
ShaderStage.Fragment => PipelineStageFlags.FragmentShaderBit,
|
||||||
ShaderStage.Compute => PipelineStageFlags.ComputeShaderBit,
|
ShaderStage.Compute => PipelineStageFlags.ComputeShaderBit,
|
||||||
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (PipelineStageFlags)0)
|
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (PipelineStageFlags)0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +90,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ResourceType.Image => DescriptorType.StorageImage,
|
ResourceType.Image => DescriptorType.StorageImage,
|
||||||
ResourceType.BufferTexture => DescriptorType.UniformTexelBuffer,
|
ResourceType.BufferTexture => DescriptorType.UniformTexelBuffer,
|
||||||
ResourceType.BufferImage => DescriptorType.StorageTexelBuffer,
|
ResourceType.BufferImage => DescriptorType.StorageTexelBuffer,
|
||||||
_ => throw new ArgumentException($"Invalid resource type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid resource type \"{type}\"."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,128 +106,128 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
AddressMode.ClampToBorder => SamplerAddressMode.ClampToBorder,
|
AddressMode.ClampToBorder => SamplerAddressMode.ClampToBorder,
|
||||||
AddressMode.MirroredRepeat => SamplerAddressMode.MirroredRepeat,
|
AddressMode.MirroredRepeat => SamplerAddressMode.MirroredRepeat,
|
||||||
AddressMode.ClampToEdge => SamplerAddressMode.ClampToEdge,
|
AddressMode.ClampToEdge => SamplerAddressMode.ClampToEdge,
|
||||||
_ => LogInvalidAndReturn(mode, nameof(AddressMode), SamplerAddressMode.ClampToEdge) // TODO: Should be clamp.
|
_ => LogInvalidAndReturn(mode, nameof(AddressMode), SamplerAddressMode.ClampToEdge), // TODO: Should be clamp.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.BlendFactor Convert(this GAL.BlendFactor factor)
|
public static BlendFactor Convert(this GAL.BlendFactor factor)
|
||||||
{
|
{
|
||||||
return factor switch
|
return factor switch
|
||||||
{
|
{
|
||||||
GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => Silk.NET.Vulkan.BlendFactor.Zero,
|
GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => BlendFactor.Zero,
|
||||||
GAL.BlendFactor.One or GAL.BlendFactor.OneGl => Silk.NET.Vulkan.BlendFactor.One,
|
GAL.BlendFactor.One or GAL.BlendFactor.OneGl => BlendFactor.One,
|
||||||
GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => Silk.NET.Vulkan.BlendFactor.SrcColor,
|
GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => BlendFactor.SrcColor,
|
||||||
GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrcColor,
|
GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => BlendFactor.OneMinusSrcColor,
|
||||||
GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => Silk.NET.Vulkan.BlendFactor.SrcAlpha,
|
GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => BlendFactor.SrcAlpha,
|
||||||
GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrcAlpha,
|
GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => BlendFactor.OneMinusSrcAlpha,
|
||||||
GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => Silk.NET.Vulkan.BlendFactor.DstAlpha,
|
GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => BlendFactor.DstAlpha,
|
||||||
GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusDstAlpha,
|
GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => BlendFactor.OneMinusDstAlpha,
|
||||||
GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => Silk.NET.Vulkan.BlendFactor.DstColor,
|
GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => BlendFactor.DstColor,
|
||||||
GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusDstColor,
|
GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => BlendFactor.OneMinusDstColor,
|
||||||
GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => Silk.NET.Vulkan.BlendFactor.SrcAlphaSaturate,
|
GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => BlendFactor.SrcAlphaSaturate,
|
||||||
GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => Silk.NET.Vulkan.BlendFactor.Src1Color,
|
GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => BlendFactor.Src1Color,
|
||||||
GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrc1Color,
|
GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => BlendFactor.OneMinusSrc1Color,
|
||||||
GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => Silk.NET.Vulkan.BlendFactor.Src1Alpha,
|
GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => BlendFactor.Src1Alpha,
|
||||||
GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrc1Alpha,
|
GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => BlendFactor.OneMinusSrc1Alpha,
|
||||||
GAL.BlendFactor.ConstantColor => Silk.NET.Vulkan.BlendFactor.ConstantColor,
|
GAL.BlendFactor.ConstantColor => BlendFactor.ConstantColor,
|
||||||
GAL.BlendFactor.OneMinusConstantColor => Silk.NET.Vulkan.BlendFactor.OneMinusConstantColor,
|
GAL.BlendFactor.OneMinusConstantColor => BlendFactor.OneMinusConstantColor,
|
||||||
GAL.BlendFactor.ConstantAlpha => Silk.NET.Vulkan.BlendFactor.ConstantAlpha,
|
GAL.BlendFactor.ConstantAlpha => BlendFactor.ConstantAlpha,
|
||||||
GAL.BlendFactor.OneMinusConstantAlpha => Silk.NET.Vulkan.BlendFactor.OneMinusConstantAlpha,
|
GAL.BlendFactor.OneMinusConstantAlpha => BlendFactor.OneMinusConstantAlpha,
|
||||||
_ => LogInvalidAndReturn(factor, nameof(GAL.BlendFactor), Silk.NET.Vulkan.BlendFactor.Zero)
|
_ => LogInvalidAndReturn(factor, nameof(GAL.BlendFactor), BlendFactor.Zero),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.AdvancedBlendOp op)
|
public static BlendOp Convert(this AdvancedBlendOp op)
|
||||||
{
|
{
|
||||||
return op switch
|
return op switch
|
||||||
{
|
{
|
||||||
GAL.AdvancedBlendOp.Zero => Silk.NET.Vulkan.BlendOp.ZeroExt,
|
AdvancedBlendOp.Zero => BlendOp.ZeroExt,
|
||||||
GAL.AdvancedBlendOp.Src => Silk.NET.Vulkan.BlendOp.SrcExt,
|
AdvancedBlendOp.Src => BlendOp.SrcExt,
|
||||||
GAL.AdvancedBlendOp.Dst => Silk.NET.Vulkan.BlendOp.DstExt,
|
AdvancedBlendOp.Dst => BlendOp.DstExt,
|
||||||
GAL.AdvancedBlendOp.SrcOver => Silk.NET.Vulkan.BlendOp.SrcOverExt,
|
AdvancedBlendOp.SrcOver => BlendOp.SrcOverExt,
|
||||||
GAL.AdvancedBlendOp.DstOver => Silk.NET.Vulkan.BlendOp.DstOverExt,
|
AdvancedBlendOp.DstOver => BlendOp.DstOverExt,
|
||||||
GAL.AdvancedBlendOp.SrcIn => Silk.NET.Vulkan.BlendOp.SrcInExt,
|
AdvancedBlendOp.SrcIn => BlendOp.SrcInExt,
|
||||||
GAL.AdvancedBlendOp.DstIn => Silk.NET.Vulkan.BlendOp.DstInExt,
|
AdvancedBlendOp.DstIn => BlendOp.DstInExt,
|
||||||
GAL.AdvancedBlendOp.SrcOut => Silk.NET.Vulkan.BlendOp.SrcOutExt,
|
AdvancedBlendOp.SrcOut => BlendOp.SrcOutExt,
|
||||||
GAL.AdvancedBlendOp.DstOut => Silk.NET.Vulkan.BlendOp.DstOutExt,
|
AdvancedBlendOp.DstOut => BlendOp.DstOutExt,
|
||||||
GAL.AdvancedBlendOp.SrcAtop => Silk.NET.Vulkan.BlendOp.SrcAtopExt,
|
AdvancedBlendOp.SrcAtop => BlendOp.SrcAtopExt,
|
||||||
GAL.AdvancedBlendOp.DstAtop => Silk.NET.Vulkan.BlendOp.DstAtopExt,
|
AdvancedBlendOp.DstAtop => BlendOp.DstAtopExt,
|
||||||
GAL.AdvancedBlendOp.Xor => Silk.NET.Vulkan.BlendOp.XorExt,
|
AdvancedBlendOp.Xor => BlendOp.XorExt,
|
||||||
GAL.AdvancedBlendOp.Plus => Silk.NET.Vulkan.BlendOp.PlusExt,
|
AdvancedBlendOp.Plus => BlendOp.PlusExt,
|
||||||
GAL.AdvancedBlendOp.PlusClamped => Silk.NET.Vulkan.BlendOp.PlusClampedExt,
|
AdvancedBlendOp.PlusClamped => BlendOp.PlusClampedExt,
|
||||||
GAL.AdvancedBlendOp.PlusClampedAlpha => Silk.NET.Vulkan.BlendOp.PlusClampedAlphaExt,
|
AdvancedBlendOp.PlusClampedAlpha => BlendOp.PlusClampedAlphaExt,
|
||||||
GAL.AdvancedBlendOp.PlusDarker => Silk.NET.Vulkan.BlendOp.PlusDarkerExt,
|
AdvancedBlendOp.PlusDarker => BlendOp.PlusDarkerExt,
|
||||||
GAL.AdvancedBlendOp.Multiply => Silk.NET.Vulkan.BlendOp.MultiplyExt,
|
AdvancedBlendOp.Multiply => BlendOp.MultiplyExt,
|
||||||
GAL.AdvancedBlendOp.Screen => Silk.NET.Vulkan.BlendOp.ScreenExt,
|
AdvancedBlendOp.Screen => BlendOp.ScreenExt,
|
||||||
GAL.AdvancedBlendOp.Overlay => Silk.NET.Vulkan.BlendOp.OverlayExt,
|
AdvancedBlendOp.Overlay => BlendOp.OverlayExt,
|
||||||
GAL.AdvancedBlendOp.Darken => Silk.NET.Vulkan.BlendOp.DarkenExt,
|
AdvancedBlendOp.Darken => BlendOp.DarkenExt,
|
||||||
GAL.AdvancedBlendOp.Lighten => Silk.NET.Vulkan.BlendOp.LightenExt,
|
AdvancedBlendOp.Lighten => BlendOp.LightenExt,
|
||||||
GAL.AdvancedBlendOp.ColorDodge => Silk.NET.Vulkan.BlendOp.ColordodgeExt,
|
AdvancedBlendOp.ColorDodge => BlendOp.ColordodgeExt,
|
||||||
GAL.AdvancedBlendOp.ColorBurn => Silk.NET.Vulkan.BlendOp.ColorburnExt,
|
AdvancedBlendOp.ColorBurn => BlendOp.ColorburnExt,
|
||||||
GAL.AdvancedBlendOp.HardLight => Silk.NET.Vulkan.BlendOp.HardlightExt,
|
AdvancedBlendOp.HardLight => BlendOp.HardlightExt,
|
||||||
GAL.AdvancedBlendOp.SoftLight => Silk.NET.Vulkan.BlendOp.SoftlightExt,
|
AdvancedBlendOp.SoftLight => BlendOp.SoftlightExt,
|
||||||
GAL.AdvancedBlendOp.Difference => Silk.NET.Vulkan.BlendOp.DifferenceExt,
|
AdvancedBlendOp.Difference => BlendOp.DifferenceExt,
|
||||||
GAL.AdvancedBlendOp.Minus => Silk.NET.Vulkan.BlendOp.MinusExt,
|
AdvancedBlendOp.Minus => BlendOp.MinusExt,
|
||||||
GAL.AdvancedBlendOp.MinusClamped => Silk.NET.Vulkan.BlendOp.MinusClampedExt,
|
AdvancedBlendOp.MinusClamped => BlendOp.MinusClampedExt,
|
||||||
GAL.AdvancedBlendOp.Exclusion => Silk.NET.Vulkan.BlendOp.ExclusionExt,
|
AdvancedBlendOp.Exclusion => BlendOp.ExclusionExt,
|
||||||
GAL.AdvancedBlendOp.Contrast => Silk.NET.Vulkan.BlendOp.ContrastExt,
|
AdvancedBlendOp.Contrast => BlendOp.ContrastExt,
|
||||||
GAL.AdvancedBlendOp.Invert => Silk.NET.Vulkan.BlendOp.InvertExt,
|
AdvancedBlendOp.Invert => BlendOp.InvertExt,
|
||||||
GAL.AdvancedBlendOp.InvertRGB => Silk.NET.Vulkan.BlendOp.InvertRgbExt,
|
AdvancedBlendOp.InvertRGB => BlendOp.InvertRgbExt,
|
||||||
GAL.AdvancedBlendOp.InvertOvg => Silk.NET.Vulkan.BlendOp.InvertOvgExt,
|
AdvancedBlendOp.InvertOvg => BlendOp.InvertOvgExt,
|
||||||
GAL.AdvancedBlendOp.LinearDodge => Silk.NET.Vulkan.BlendOp.LineardodgeExt,
|
AdvancedBlendOp.LinearDodge => BlendOp.LineardodgeExt,
|
||||||
GAL.AdvancedBlendOp.LinearBurn => Silk.NET.Vulkan.BlendOp.LinearburnExt,
|
AdvancedBlendOp.LinearBurn => BlendOp.LinearburnExt,
|
||||||
GAL.AdvancedBlendOp.VividLight => Silk.NET.Vulkan.BlendOp.VividlightExt,
|
AdvancedBlendOp.VividLight => BlendOp.VividlightExt,
|
||||||
GAL.AdvancedBlendOp.LinearLight => Silk.NET.Vulkan.BlendOp.LinearlightExt,
|
AdvancedBlendOp.LinearLight => BlendOp.LinearlightExt,
|
||||||
GAL.AdvancedBlendOp.PinLight => Silk.NET.Vulkan.BlendOp.PinlightExt,
|
AdvancedBlendOp.PinLight => BlendOp.PinlightExt,
|
||||||
GAL.AdvancedBlendOp.HardMix => Silk.NET.Vulkan.BlendOp.HardmixExt,
|
AdvancedBlendOp.HardMix => BlendOp.HardmixExt,
|
||||||
GAL.AdvancedBlendOp.Red => Silk.NET.Vulkan.BlendOp.RedExt,
|
AdvancedBlendOp.Red => BlendOp.RedExt,
|
||||||
GAL.AdvancedBlendOp.Green => Silk.NET.Vulkan.BlendOp.GreenExt,
|
AdvancedBlendOp.Green => BlendOp.GreenExt,
|
||||||
GAL.AdvancedBlendOp.Blue => Silk.NET.Vulkan.BlendOp.BlueExt,
|
AdvancedBlendOp.Blue => BlendOp.BlueExt,
|
||||||
GAL.AdvancedBlendOp.HslHue => Silk.NET.Vulkan.BlendOp.HslHueExt,
|
AdvancedBlendOp.HslHue => BlendOp.HslHueExt,
|
||||||
GAL.AdvancedBlendOp.HslSaturation => Silk.NET.Vulkan.BlendOp.HslSaturationExt,
|
AdvancedBlendOp.HslSaturation => BlendOp.HslSaturationExt,
|
||||||
GAL.AdvancedBlendOp.HslColor => Silk.NET.Vulkan.BlendOp.HslColorExt,
|
AdvancedBlendOp.HslColor => BlendOp.HslColorExt,
|
||||||
GAL.AdvancedBlendOp.HslLuminosity => Silk.NET.Vulkan.BlendOp.HslLuminosityExt,
|
AdvancedBlendOp.HslLuminosity => BlendOp.HslLuminosityExt,
|
||||||
_ => LogInvalidAndReturn(op, nameof(GAL.AdvancedBlendOp), Silk.NET.Vulkan.BlendOp.Add)
|
_ => LogInvalidAndReturn(op, nameof(AdvancedBlendOp), BlendOp.Add),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.BlendOp op)
|
public static BlendOp Convert(this GAL.BlendOp op)
|
||||||
{
|
{
|
||||||
return op switch
|
return op switch
|
||||||
{
|
{
|
||||||
GAL.BlendOp.Add or GAL.BlendOp.AddGl => Silk.NET.Vulkan.BlendOp.Add,
|
GAL.BlendOp.Add or GAL.BlendOp.AddGl => BlendOp.Add,
|
||||||
GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => Silk.NET.Vulkan.BlendOp.Subtract,
|
GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => BlendOp.Subtract,
|
||||||
GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => Silk.NET.Vulkan.BlendOp.ReverseSubtract,
|
GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => BlendOp.ReverseSubtract,
|
||||||
GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => Silk.NET.Vulkan.BlendOp.Min,
|
GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => BlendOp.Min,
|
||||||
GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => Silk.NET.Vulkan.BlendOp.Max,
|
GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => BlendOp.Max,
|
||||||
_ => LogInvalidAndReturn(op, nameof(GAL.BlendOp), Silk.NET.Vulkan.BlendOp.Add)
|
_ => LogInvalidAndReturn(op, nameof(GAL.BlendOp), BlendOp.Add),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.BlendOverlapEXT Convert(this GAL.AdvancedBlendOverlap overlap)
|
public static BlendOverlapEXT Convert(this AdvancedBlendOverlap overlap)
|
||||||
{
|
{
|
||||||
return overlap switch
|
return overlap switch
|
||||||
{
|
{
|
||||||
GAL.AdvancedBlendOverlap.Uncorrelated => Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt,
|
AdvancedBlendOverlap.Uncorrelated => BlendOverlapEXT.UncorrelatedExt,
|
||||||
GAL.AdvancedBlendOverlap.Disjoint => Silk.NET.Vulkan.BlendOverlapEXT.DisjointExt,
|
AdvancedBlendOverlap.Disjoint => BlendOverlapEXT.DisjointExt,
|
||||||
GAL.AdvancedBlendOverlap.Conjoint => Silk.NET.Vulkan.BlendOverlapEXT.ConjointExt,
|
AdvancedBlendOverlap.Conjoint => BlendOverlapEXT.ConjointExt,
|
||||||
_ => LogInvalidAndReturn(overlap, nameof(GAL.AdvancedBlendOverlap), Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt)
|
_ => LogInvalidAndReturn(overlap, nameof(AdvancedBlendOverlap), BlendOverlapEXT.UncorrelatedExt),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.CompareOp Convert(this GAL.CompareOp op)
|
public static CompareOp Convert(this GAL.CompareOp op)
|
||||||
{
|
{
|
||||||
return op switch
|
return op switch
|
||||||
{
|
{
|
||||||
GAL.CompareOp.Never or GAL.CompareOp.NeverGl => Silk.NET.Vulkan.CompareOp.Never,
|
GAL.CompareOp.Never or GAL.CompareOp.NeverGl => CompareOp.Never,
|
||||||
GAL.CompareOp.Less or GAL.CompareOp.LessGl => Silk.NET.Vulkan.CompareOp.Less,
|
GAL.CompareOp.Less or GAL.CompareOp.LessGl => CompareOp.Less,
|
||||||
GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => Silk.NET.Vulkan.CompareOp.Equal,
|
GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => CompareOp.Equal,
|
||||||
GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => Silk.NET.Vulkan.CompareOp.LessOrEqual,
|
GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => CompareOp.LessOrEqual,
|
||||||
GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => Silk.NET.Vulkan.CompareOp.Greater,
|
GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => CompareOp.Greater,
|
||||||
GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => Silk.NET.Vulkan.CompareOp.NotEqual,
|
GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => CompareOp.NotEqual,
|
||||||
GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => Silk.NET.Vulkan.CompareOp.GreaterOrEqual,
|
GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => CompareOp.GreaterOrEqual,
|
||||||
GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => Silk.NET.Vulkan.CompareOp.Always,
|
GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => CompareOp.Always,
|
||||||
_ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), Silk.NET.Vulkan.CompareOp.Never)
|
_ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), CompareOp.Never),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,29 +238,29 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Face.Back => CullModeFlags.BackBit,
|
Face.Back => CullModeFlags.BackBit,
|
||||||
Face.Front => CullModeFlags.FrontBit,
|
Face.Front => CullModeFlags.FrontBit,
|
||||||
Face.FrontAndBack => CullModeFlags.FrontAndBack,
|
Face.FrontAndBack => CullModeFlags.FrontAndBack,
|
||||||
_ => LogInvalidAndReturn(face, nameof(Face), CullModeFlags.BackBit)
|
_ => LogInvalidAndReturn(face, nameof(Face), CullModeFlags.BackBit),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.FrontFace Convert(this GAL.FrontFace frontFace)
|
public static FrontFace Convert(this GAL.FrontFace frontFace)
|
||||||
{
|
{
|
||||||
// Flipped to account for origin differences.
|
// Flipped to account for origin differences.
|
||||||
return frontFace switch
|
return frontFace switch
|
||||||
{
|
{
|
||||||
GAL.FrontFace.Clockwise => Silk.NET.Vulkan.FrontFace.CounterClockwise,
|
GAL.FrontFace.Clockwise => FrontFace.CounterClockwise,
|
||||||
GAL.FrontFace.CounterClockwise => Silk.NET.Vulkan.FrontFace.Clockwise,
|
GAL.FrontFace.CounterClockwise => FrontFace.Clockwise,
|
||||||
_ => LogInvalidAndReturn(frontFace, nameof(GAL.FrontFace), Silk.NET.Vulkan.FrontFace.Clockwise)
|
_ => LogInvalidAndReturn(frontFace, nameof(GAL.FrontFace), FrontFace.Clockwise),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.IndexType Convert(this GAL.IndexType type)
|
public static IndexType Convert(this GAL.IndexType type)
|
||||||
{
|
{
|
||||||
return type switch
|
return type switch
|
||||||
{
|
{
|
||||||
GAL.IndexType.UByte => Silk.NET.Vulkan.IndexType.Uint8Ext,
|
GAL.IndexType.UByte => IndexType.Uint8Ext,
|
||||||
GAL.IndexType.UShort => Silk.NET.Vulkan.IndexType.Uint16,
|
GAL.IndexType.UShort => IndexType.Uint16,
|
||||||
GAL.IndexType.UInt => Silk.NET.Vulkan.IndexType.Uint32,
|
GAL.IndexType.UInt => IndexType.Uint32,
|
||||||
_ => LogInvalidAndReturn(type, nameof(GAL.IndexType), Silk.NET.Vulkan.IndexType.Uint16)
|
_ => LogInvalidAndReturn(type, nameof(GAL.IndexType), IndexType.Uint16),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +270,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
MagFilter.Nearest => Filter.Nearest,
|
MagFilter.Nearest => Filter.Nearest,
|
||||||
MagFilter.Linear => Filter.Linear,
|
MagFilter.Linear => Filter.Linear,
|
||||||
_ => LogInvalidAndReturn(filter, nameof(MagFilter), Filter.Nearest)
|
_ => LogInvalidAndReturn(filter, nameof(MagFilter), Filter.Nearest),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,45 +284,45 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
MinFilter.LinearMipmapNearest => (Filter.Linear, SamplerMipmapMode.Nearest),
|
MinFilter.LinearMipmapNearest => (Filter.Linear, SamplerMipmapMode.Nearest),
|
||||||
MinFilter.NearestMipmapLinear => (Filter.Nearest, SamplerMipmapMode.Linear),
|
MinFilter.NearestMipmapLinear => (Filter.Nearest, SamplerMipmapMode.Linear),
|
||||||
MinFilter.LinearMipmapLinear => (Filter.Linear, SamplerMipmapMode.Linear),
|
MinFilter.LinearMipmapLinear => (Filter.Linear, SamplerMipmapMode.Linear),
|
||||||
_ => LogInvalidAndReturn(filter, nameof(MinFilter), (Filter.Nearest, SamplerMipmapMode.Nearest))
|
_ => LogInvalidAndReturn(filter, nameof(MinFilter), (Filter.Nearest, SamplerMipmapMode.Nearest)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.PrimitiveTopology Convert(this GAL.PrimitiveTopology topology)
|
public static PrimitiveTopology Convert(this GAL.PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
return topology switch
|
return topology switch
|
||||||
{
|
{
|
||||||
GAL.PrimitiveTopology.Points => Silk.NET.Vulkan.PrimitiveTopology.PointList,
|
GAL.PrimitiveTopology.Points => PrimitiveTopology.PointList,
|
||||||
GAL.PrimitiveTopology.Lines => Silk.NET.Vulkan.PrimitiveTopology.LineList,
|
GAL.PrimitiveTopology.Lines => PrimitiveTopology.LineList,
|
||||||
GAL.PrimitiveTopology.LineStrip => Silk.NET.Vulkan.PrimitiveTopology.LineStrip,
|
GAL.PrimitiveTopology.LineStrip => PrimitiveTopology.LineStrip,
|
||||||
GAL.PrimitiveTopology.Triangles => Silk.NET.Vulkan.PrimitiveTopology.TriangleList,
|
GAL.PrimitiveTopology.Triangles => PrimitiveTopology.TriangleList,
|
||||||
GAL.PrimitiveTopology.TriangleStrip => Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip,
|
GAL.PrimitiveTopology.TriangleStrip => PrimitiveTopology.TriangleStrip,
|
||||||
GAL.PrimitiveTopology.TriangleFan => Silk.NET.Vulkan.PrimitiveTopology.TriangleFan,
|
GAL.PrimitiveTopology.TriangleFan => PrimitiveTopology.TriangleFan,
|
||||||
GAL.PrimitiveTopology.LinesAdjacency => Silk.NET.Vulkan.PrimitiveTopology.LineListWithAdjacency,
|
GAL.PrimitiveTopology.LinesAdjacency => PrimitiveTopology.LineListWithAdjacency,
|
||||||
GAL.PrimitiveTopology.LineStripAdjacency => Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency,
|
GAL.PrimitiveTopology.LineStripAdjacency => PrimitiveTopology.LineStripWithAdjacency,
|
||||||
GAL.PrimitiveTopology.TrianglesAdjacency => Silk.NET.Vulkan.PrimitiveTopology.TriangleListWithAdjacency,
|
GAL.PrimitiveTopology.TrianglesAdjacency => PrimitiveTopology.TriangleListWithAdjacency,
|
||||||
GAL.PrimitiveTopology.TriangleStripAdjacency => Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency,
|
GAL.PrimitiveTopology.TriangleStripAdjacency => PrimitiveTopology.TriangleStripWithAdjacency,
|
||||||
GAL.PrimitiveTopology.Patches => Silk.NET.Vulkan.PrimitiveTopology.PatchList,
|
GAL.PrimitiveTopology.Patches => PrimitiveTopology.PatchList,
|
||||||
GAL.PrimitiveTopology.Polygon => Silk.NET.Vulkan.PrimitiveTopology.TriangleFan,
|
GAL.PrimitiveTopology.Polygon => PrimitiveTopology.TriangleFan,
|
||||||
GAL.PrimitiveTopology.Quads => throw new NotSupportedException("Quad topology is not available in Vulkan."),
|
GAL.PrimitiveTopology.Quads => throw new NotSupportedException("Quad topology is not available in Vulkan."),
|
||||||
GAL.PrimitiveTopology.QuadStrip => throw new NotSupportedException("QuadStrip topology is not available in Vulkan."),
|
GAL.PrimitiveTopology.QuadStrip => throw new NotSupportedException("QuadStrip topology is not available in Vulkan."),
|
||||||
_ => LogInvalidAndReturn(topology, nameof(GAL.PrimitiveTopology), Silk.NET.Vulkan.PrimitiveTopology.TriangleList)
|
_ => LogInvalidAndReturn(topology, nameof(GAL.PrimitiveTopology), PrimitiveTopology.TriangleList),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Silk.NET.Vulkan.StencilOp Convert(this GAL.StencilOp op)
|
public static StencilOp Convert(this GAL.StencilOp op)
|
||||||
{
|
{
|
||||||
return op switch
|
return op switch
|
||||||
{
|
{
|
||||||
GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => Silk.NET.Vulkan.StencilOp.Keep,
|
GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => StencilOp.Keep,
|
||||||
GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => Silk.NET.Vulkan.StencilOp.Zero,
|
GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => StencilOp.Zero,
|
||||||
GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => Silk.NET.Vulkan.StencilOp.Replace,
|
GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => StencilOp.Replace,
|
||||||
GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => Silk.NET.Vulkan.StencilOp.IncrementAndClamp,
|
GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => StencilOp.IncrementAndClamp,
|
||||||
GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => Silk.NET.Vulkan.StencilOp.DecrementAndClamp,
|
GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => StencilOp.DecrementAndClamp,
|
||||||
GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => Silk.NET.Vulkan.StencilOp.Invert,
|
GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => StencilOp.Invert,
|
||||||
GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => Silk.NET.Vulkan.StencilOp.IncrementAndWrap,
|
GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => StencilOp.IncrementAndWrap,
|
||||||
GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => Silk.NET.Vulkan.StencilOp.DecrementAndWrap,
|
GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => StencilOp.DecrementAndWrap,
|
||||||
_ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), Silk.NET.Vulkan.StencilOp.Keep)
|
_ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), StencilOp.Keep),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,7 +336,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SwizzleComponent.Green => ComponentSwizzle.G,
|
SwizzleComponent.Green => ComponentSwizzle.G,
|
||||||
SwizzleComponent.Blue => ComponentSwizzle.B,
|
SwizzleComponent.Blue => ComponentSwizzle.B,
|
||||||
SwizzleComponent.Alpha => ComponentSwizzle.A,
|
SwizzleComponent.Alpha => ComponentSwizzle.A,
|
||||||
_ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), ComponentSwizzle.Zero)
|
_ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), ComponentSwizzle.Zero),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +353,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Target.Cubemap or
|
Target.Cubemap or
|
||||||
Target.CubemapArray => ImageType.Type2D,
|
Target.CubemapArray => ImageType.Type2D,
|
||||||
Target.Texture3D => ImageType.Type3D,
|
Target.Texture3D => ImageType.Type3D,
|
||||||
_ => LogInvalidAndReturn(target, nameof(Target), ImageType.Type2D)
|
_ => LogInvalidAndReturn(target, nameof(Target), ImageType.Type2D),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,33 +368,33 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Target.Texture2DArray => ImageViewType.Type2DArray,
|
Target.Texture2DArray => ImageViewType.Type2DArray,
|
||||||
Target.Cubemap => ImageViewType.TypeCube,
|
Target.Cubemap => ImageViewType.TypeCube,
|
||||||
Target.CubemapArray => ImageViewType.TypeCubeArray,
|
Target.CubemapArray => ImageViewType.TypeCubeArray,
|
||||||
_ => LogInvalidAndReturn(target, nameof(Target), ImageViewType.Type2D)
|
_ => LogInvalidAndReturn(target, nameof(Target), ImageViewType.Type2D),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageAspectFlags ConvertAspectFlags(this GAL.Format format)
|
public static ImageAspectFlags ConvertAspectFlags(this Format format)
|
||||||
{
|
{
|
||||||
return format switch
|
return format switch
|
||||||
{
|
{
|
||||||
GAL.Format.D16Unorm or GAL.Format.D32Float => ImageAspectFlags.DepthBit,
|
Format.D16Unorm or Format.D32Float => ImageAspectFlags.DepthBit,
|
||||||
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
|
Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||||
GAL.Format.D24UnormS8Uint or
|
Format.D24UnormS8Uint or
|
||||||
GAL.Format.D32FloatS8Uint or
|
Format.D32FloatS8Uint or
|
||||||
GAL.Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
||||||
_ => ImageAspectFlags.ColorBit
|
_ => ImageAspectFlags.ColorBit,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageAspectFlags ConvertAspectFlags(this GAL.Format format, DepthStencilMode depthStencilMode)
|
public static ImageAspectFlags ConvertAspectFlags(this Format format, DepthStencilMode depthStencilMode)
|
||||||
{
|
{
|
||||||
return format switch
|
return format switch
|
||||||
{
|
{
|
||||||
GAL.Format.D16Unorm or GAL.Format.D32Float => ImageAspectFlags.DepthBit,
|
Format.D16Unorm or Format.D32Float => ImageAspectFlags.DepthBit,
|
||||||
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
|
Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||||
GAL.Format.D24UnormS8Uint or
|
Format.D24UnormS8Uint or
|
||||||
GAL.Format.D32FloatS8Uint or
|
Format.D32FloatS8Uint or
|
||||||
GAL.Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
|
Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
|
||||||
_ => ImageAspectFlags.ColorBit
|
_ => ImageAspectFlags.ColorBit,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +418,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
LogicalOp.OrInverted => LogicOp.OrInverted,
|
LogicalOp.OrInverted => LogicOp.OrInverted,
|
||||||
LogicalOp.Nand => LogicOp.Nand,
|
LogicalOp.Nand => LogicOp.Nand,
|
||||||
LogicalOp.Set => LogicOp.Set,
|
LogicalOp.Set => LogicOp.Set,
|
||||||
_ => LogInvalidAndReturn(op, nameof(LogicalOp), LogicOp.Copy)
|
_ => LogInvalidAndReturn(op, nameof(LogicalOp), LogicOp.Copy),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +427,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return access switch
|
return access switch
|
||||||
{
|
{
|
||||||
BufferAccess.FlushPersistent => BufferAllocationType.HostMapped,
|
BufferAccess.FlushPersistent => BufferAllocationType.HostMapped,
|
||||||
_ => BufferAllocationType.Auto
|
_ => BufferAllocationType.Auto,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_api = api;
|
_api = api;
|
||||||
_device = device;
|
_device = device;
|
||||||
|
|
||||||
var fenceCreateInfo = new FenceCreateInfo()
|
var fenceCreateInfo = new FenceCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.FenceCreateInfo
|
SType = StructureType.FenceCreateInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CreateFence(device, in fenceCreateInfo, null, out _fence).ThrowOnError();
|
api.CreateFence(device, in fenceCreateInfo, null, out _fence).ThrowOnError();
|
||||||
|
@ -70,7 +70,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Span<Fence> fences = stackalloc Fence[]
|
Span<Fence> fences = stackalloc Fence[]
|
||||||
{
|
{
|
||||||
_fence
|
_fence,
|
||||||
};
|
};
|
||||||
|
|
||||||
FenceHelper.WaitAllIndefinitely(_api, _device, fences);
|
FenceHelper.WaitAllIndefinitely(_api, _device, fences);
|
||||||
|
@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Span<Fence> fences = stackalloc Fence[]
|
Span<Fence> fences = stackalloc Fence[]
|
||||||
{
|
{
|
||||||
_fence
|
_fence,
|
||||||
};
|
};
|
||||||
|
|
||||||
return FenceHelper.AllSignaled(_api, _device, fences);
|
return FenceHelper.AllSignaled(_api, _device, fences);
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
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
|
||||||
|
@ -19,15 +20,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_api = api;
|
_api = api;
|
||||||
_physicalDevice = physicalDevice;
|
_physicalDevice = physicalDevice;
|
||||||
|
|
||||||
int totalFormats = Enum.GetNames(typeof(GAL.Format)).Length;
|
int totalFormats = Enum.GetNames(typeof(Format)).Length;
|
||||||
|
|
||||||
_bufferTable = new FormatFeatureFlags[totalFormats];
|
_bufferTable = new FormatFeatureFlags[totalFormats];
|
||||||
_optimalTable = new FormatFeatureFlags[totalFormats];
|
_optimalTable = new FormatFeatureFlags[totalFormats];
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BufferFormatsSupport(FormatFeatureFlags flags, params GAL.Format[] formats)
|
public bool BufferFormatsSupport(FormatFeatureFlags flags, params Format[] formats)
|
||||||
{
|
{
|
||||||
foreach (GAL.Format format in formats)
|
foreach (Format format in formats)
|
||||||
{
|
{
|
||||||
if (!BufferFormatSupports(flags, format))
|
if (!BufferFormatSupports(flags, format))
|
||||||
{
|
{
|
||||||
|
@ -38,9 +39,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OptimalFormatsSupport(FormatFeatureFlags flags, params GAL.Format[] formats)
|
public bool OptimalFormatsSupport(FormatFeatureFlags flags, params Format[] formats)
|
||||||
{
|
{
|
||||||
foreach (GAL.Format format in formats)
|
foreach (Format format in formats)
|
||||||
{
|
{
|
||||||
if (!OptimalFormatSupports(flags, format))
|
if (!OptimalFormatSupports(flags, format))
|
||||||
{
|
{
|
||||||
|
@ -51,7 +52,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BufferFormatSupports(FormatFeatureFlags flags, GAL.Format format)
|
public bool BufferFormatSupports(FormatFeatureFlags flags, Format format)
|
||||||
{
|
{
|
||||||
var formatFeatureFlags = _bufferTable[(int)format];
|
var formatFeatureFlags = _bufferTable[(int)format];
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return (fp.BufferFeatures & flags) == flags;
|
return (fp.BufferFeatures & flags) == flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OptimalFormatSupports(FormatFeatureFlags flags, GAL.Format format)
|
public bool OptimalFormatSupports(FormatFeatureFlags flags, Format format)
|
||||||
{
|
{
|
||||||
var formatFeatureFlags = _optimalTable[(int)format];
|
var formatFeatureFlags = _optimalTable[(int)format];
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return (formatFeatureFlags & flags) == flags;
|
return (formatFeatureFlags & flags) == flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VkFormat ConvertToVkFormat(GAL.Format srcFormat)
|
public VkFormat ConvertToVkFormat(Format srcFormat)
|
||||||
{
|
{
|
||||||
var format = FormatTable.GetFormat(srcFormat);
|
var format = FormatTable.GetFormat(srcFormat);
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
format = VkFormat.D32SfloatS8Uint;
|
format = VkFormat.D32SfloatS8Uint;
|
||||||
}
|
}
|
||||||
else if (srcFormat == GAL.Format.R4G4B4A4Unorm)
|
else if (srcFormat == Format.R4G4B4A4Unorm)
|
||||||
{
|
{
|
||||||
format = VkFormat.R4G4B4A4UnormPack16;
|
format = VkFormat.R4G4B4A4UnormPack16;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +129,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VkFormat ConvertToVertexVkFormat(GAL.Format srcFormat)
|
public VkFormat ConvertToVertexVkFormat(Format srcFormat)
|
||||||
{
|
{
|
||||||
var format = FormatTable.GetFormat(srcFormat);
|
var format = FormatTable.GetFormat(srcFormat);
|
||||||
|
|
||||||
|
@ -138,13 +139,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// The format is not supported. Can we convert it to an alternative format?
|
// The format is not supported. Can we convert it to an alternative format?
|
||||||
switch (srcFormat)
|
switch (srcFormat)
|
||||||
{
|
{
|
||||||
case GAL.Format.R16G16B16Float:
|
case Format.R16G16B16Float:
|
||||||
format = VkFormat.R16G16B16A16Sfloat;
|
format = VkFormat.R16G16B16A16Sfloat;
|
||||||
break;
|
break;
|
||||||
case GAL.Format.R16G16B16Sint:
|
case Format.R16G16B16Sint:
|
||||||
format = VkFormat.R16G16B16A16Sint;
|
format = VkFormat.R16G16B16A16Sint;
|
||||||
break;
|
break;
|
||||||
case GAL.Format.R16G16B16Uint:
|
case Format.R16G16B16Uint:
|
||||||
format = VkFormat.R16G16B16A16Uint;
|
format = VkFormat.R16G16B16A16Uint;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -156,16 +157,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsD24S8(GAL.Format format)
|
public static bool IsD24S8(Format format)
|
||||||
{
|
{
|
||||||
return format == GAL.Format.D24UnormS8Uint || format == GAL.Format.S8UintD24Unorm;
|
return format == Format.D24UnormS8Uint || format == Format.S8UintD24Unorm;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsRGB16IntFloat(GAL.Format format)
|
private static bool IsRGB16IntFloat(Format format)
|
||||||
{
|
{
|
||||||
return format == GAL.Format.R16G16B16Float ||
|
return format == Format.R16G16B16Float ||
|
||||||
format == GAL.Format.R16G16B16Sint ||
|
format == Format.R16G16B16Sint ||
|
||||||
format == GAL.Format.R16G16B16Uint;
|
format == Format.R16G16B16Uint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
_table = new VkFormat[Enum.GetNames(typeof(Format)).Length];
|
_table = new VkFormat[Enum.GetNames(typeof(Format)).Length];
|
||||||
|
|
||||||
|
#pragma warning disable IDE0055 // Disable formatting
|
||||||
Add(Format.R8Unorm, VkFormat.R8Unorm);
|
Add(Format.R8Unorm, VkFormat.R8Unorm);
|
||||||
Add(Format.R8Snorm, VkFormat.R8SNorm);
|
Add(Format.R8Snorm, VkFormat.R8SNorm);
|
||||||
Add(Format.R8Uint, VkFormat.R8Uint);
|
Add(Format.R8Uint, VkFormat.R8Uint);
|
||||||
|
@ -157,6 +158,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Add(Format.A1B5G5R5Unorm, VkFormat.R5G5B5A1UnormPack16);
|
Add(Format.A1B5G5R5Unorm, VkFormat.R5G5B5A1UnormPack16);
|
||||||
Add(Format.B8G8R8A8Unorm, VkFormat.B8G8R8A8Unorm);
|
Add(Format.B8G8R8A8Unorm, VkFormat.B8G8R8A8Unorm);
|
||||||
Add(Format.B8G8R8A8Srgb, VkFormat.B8G8R8A8Srgb);
|
Add(Format.B8G8R8A8Srgb, VkFormat.B8G8R8A8Srgb);
|
||||||
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Add(Format format, VkFormat vkFormat)
|
private static void Add(Format format, VkFormat vkFormat)
|
||||||
|
@ -175,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Format.R8G8B8A8Srgb => Format.R8G8B8A8Unorm,
|
Format.R8G8B8A8Srgb => Format.R8G8B8A8Unorm,
|
||||||
Format.B8G8R8A8Srgb => Format.B8G8R8A8Unorm,
|
Format.B8G8R8A8Srgb => Format.B8G8R8A8Unorm,
|
||||||
_ => format
|
_ => format,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,121 +282,61 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public static VkFormat DropLastComponent(VkFormat format)
|
public static VkFormat DropLastComponent(VkFormat format)
|
||||||
{
|
{
|
||||||
switch (format)
|
return format switch
|
||||||
{
|
{
|
||||||
case VkFormat.R8G8Unorm:
|
VkFormat.R8G8Unorm => VkFormat.R8Unorm,
|
||||||
return VkFormat.R8Unorm;
|
VkFormat.R8G8SNorm => VkFormat.R8SNorm,
|
||||||
case VkFormat.R8G8SNorm:
|
VkFormat.R8G8Uint => VkFormat.R8Uint,
|
||||||
return VkFormat.R8SNorm;
|
VkFormat.R8G8Sint => VkFormat.R8Sint,
|
||||||
case VkFormat.R8G8Uint:
|
VkFormat.R8G8Uscaled => VkFormat.R8Uscaled,
|
||||||
return VkFormat.R8Uint;
|
VkFormat.R8G8Sscaled => VkFormat.R8Sscaled,
|
||||||
case VkFormat.R8G8Sint:
|
VkFormat.R8G8B8Unorm => VkFormat.R8G8Unorm,
|
||||||
return VkFormat.R8Sint;
|
VkFormat.R8G8B8SNorm => VkFormat.R8G8SNorm,
|
||||||
case VkFormat.R8G8Uscaled:
|
VkFormat.R8G8B8Uint => VkFormat.R8G8Uint,
|
||||||
return VkFormat.R8Uscaled;
|
VkFormat.R8G8B8Sint => VkFormat.R8G8Sint,
|
||||||
case VkFormat.R8G8Sscaled:
|
VkFormat.R8G8B8Uscaled => VkFormat.R8G8Uscaled,
|
||||||
return VkFormat.R8Sscaled;
|
VkFormat.R8G8B8Sscaled => VkFormat.R8G8Sscaled,
|
||||||
|
VkFormat.R8G8B8A8Unorm => VkFormat.R8G8B8Unorm,
|
||||||
case VkFormat.R8G8B8Unorm:
|
VkFormat.R8G8B8A8SNorm => VkFormat.R8G8B8SNorm,
|
||||||
return VkFormat.R8G8Unorm;
|
VkFormat.R8G8B8A8Uint => VkFormat.R8G8B8Uint,
|
||||||
case VkFormat.R8G8B8SNorm:
|
VkFormat.R8G8B8A8Sint => VkFormat.R8G8B8Sint,
|
||||||
return VkFormat.R8G8SNorm;
|
VkFormat.R8G8B8A8Srgb => VkFormat.R8G8B8Srgb,
|
||||||
case VkFormat.R8G8B8Uint:
|
VkFormat.R8G8B8A8Uscaled => VkFormat.R8G8B8Uscaled,
|
||||||
return VkFormat.R8G8Uint;
|
VkFormat.R8G8B8A8Sscaled => VkFormat.R8G8B8Sscaled,
|
||||||
case VkFormat.R8G8B8Sint:
|
VkFormat.B8G8R8A8Unorm => VkFormat.B8G8R8Unorm,
|
||||||
return VkFormat.R8G8Sint;
|
VkFormat.B8G8R8A8Srgb => VkFormat.B8G8R8Srgb,
|
||||||
case VkFormat.R8G8B8Uscaled:
|
VkFormat.R16G16Sfloat => VkFormat.R16Sfloat,
|
||||||
return VkFormat.R8G8Uscaled;
|
VkFormat.R16G16Unorm => VkFormat.R16Unorm,
|
||||||
case VkFormat.R8G8B8Sscaled:
|
VkFormat.R16G16SNorm => VkFormat.R16SNorm,
|
||||||
return VkFormat.R8G8Sscaled;
|
VkFormat.R16G16Uint => VkFormat.R16Uint,
|
||||||
|
VkFormat.R16G16Sint => VkFormat.R16Sint,
|
||||||
case VkFormat.R8G8B8A8Unorm:
|
VkFormat.R16G16Uscaled => VkFormat.R16Uscaled,
|
||||||
return VkFormat.R8G8B8Unorm;
|
VkFormat.R16G16Sscaled => VkFormat.R16Sscaled,
|
||||||
case VkFormat.R8G8B8A8SNorm:
|
VkFormat.R16G16B16Sfloat => VkFormat.R16G16Sfloat,
|
||||||
return VkFormat.R8G8B8SNorm;
|
VkFormat.R16G16B16Unorm => VkFormat.R16G16Unorm,
|
||||||
case VkFormat.R8G8B8A8Uint:
|
VkFormat.R16G16B16SNorm => VkFormat.R16G16SNorm,
|
||||||
return VkFormat.R8G8B8Uint;
|
VkFormat.R16G16B16Uint => VkFormat.R16G16Uint,
|
||||||
case VkFormat.R8G8B8A8Sint:
|
VkFormat.R16G16B16Sint => VkFormat.R16G16Sint,
|
||||||
return VkFormat.R8G8B8Sint;
|
VkFormat.R16G16B16Uscaled => VkFormat.R16G16Uscaled,
|
||||||
case VkFormat.R8G8B8A8Srgb:
|
VkFormat.R16G16B16Sscaled => VkFormat.R16G16Sscaled,
|
||||||
return VkFormat.R8G8B8Srgb;
|
VkFormat.R16G16B16A16Sfloat => VkFormat.R16G16B16Sfloat,
|
||||||
case VkFormat.R8G8B8A8Uscaled:
|
VkFormat.R16G16B16A16Unorm => VkFormat.R16G16B16Unorm,
|
||||||
return VkFormat.R8G8B8Uscaled;
|
VkFormat.R16G16B16A16SNorm => VkFormat.R16G16B16SNorm,
|
||||||
case VkFormat.R8G8B8A8Sscaled:
|
VkFormat.R16G16B16A16Uint => VkFormat.R16G16B16Uint,
|
||||||
return VkFormat.R8G8B8Sscaled;
|
VkFormat.R16G16B16A16Sint => VkFormat.R16G16B16Sint,
|
||||||
case VkFormat.B8G8R8A8Unorm:
|
VkFormat.R16G16B16A16Uscaled => VkFormat.R16G16B16Uscaled,
|
||||||
return VkFormat.B8G8R8Unorm;
|
VkFormat.R16G16B16A16Sscaled => VkFormat.R16G16B16Sscaled,
|
||||||
case VkFormat.B8G8R8A8Srgb:
|
VkFormat.R32G32Sfloat => VkFormat.R32Sfloat,
|
||||||
return VkFormat.B8G8R8Srgb;
|
VkFormat.R32G32Uint => VkFormat.R32Uint,
|
||||||
|
VkFormat.R32G32Sint => VkFormat.R32Sint,
|
||||||
case VkFormat.R16G16Sfloat:
|
VkFormat.R32G32B32Sfloat => VkFormat.R32G32Sfloat,
|
||||||
return VkFormat.R16Sfloat;
|
VkFormat.R32G32B32Uint => VkFormat.R32G32Uint,
|
||||||
case VkFormat.R16G16Unorm:
|
VkFormat.R32G32B32Sint => VkFormat.R32G32Sint,
|
||||||
return VkFormat.R16Unorm;
|
VkFormat.R32G32B32A32Sfloat => VkFormat.R32G32B32Sfloat,
|
||||||
case VkFormat.R16G16SNorm:
|
VkFormat.R32G32B32A32Uint => VkFormat.R32G32B32Uint,
|
||||||
return VkFormat.R16SNorm;
|
VkFormat.R32G32B32A32Sint => VkFormat.R32G32B32Sint,
|
||||||
case VkFormat.R16G16Uint:
|
_ => format,
|
||||||
return VkFormat.R16Uint;
|
};
|
||||||
case VkFormat.R16G16Sint:
|
|
||||||
return VkFormat.R16Sint;
|
|
||||||
case VkFormat.R16G16Uscaled:
|
|
||||||
return VkFormat.R16Uscaled;
|
|
||||||
case VkFormat.R16G16Sscaled:
|
|
||||||
return VkFormat.R16Sscaled;
|
|
||||||
|
|
||||||
case VkFormat.R16G16B16Sfloat:
|
|
||||||
return VkFormat.R16G16Sfloat;
|
|
||||||
case VkFormat.R16G16B16Unorm:
|
|
||||||
return VkFormat.R16G16Unorm;
|
|
||||||
case VkFormat.R16G16B16SNorm:
|
|
||||||
return VkFormat.R16G16SNorm;
|
|
||||||
case VkFormat.R16G16B16Uint:
|
|
||||||
return VkFormat.R16G16Uint;
|
|
||||||
case VkFormat.R16G16B16Sint:
|
|
||||||
return VkFormat.R16G16Sint;
|
|
||||||
case VkFormat.R16G16B16Uscaled:
|
|
||||||
return VkFormat.R16G16Uscaled;
|
|
||||||
case VkFormat.R16G16B16Sscaled:
|
|
||||||
return VkFormat.R16G16Sscaled;
|
|
||||||
|
|
||||||
case VkFormat.R16G16B16A16Sfloat:
|
|
||||||
return VkFormat.R16G16B16Sfloat;
|
|
||||||
case VkFormat.R16G16B16A16Unorm:
|
|
||||||
return VkFormat.R16G16B16Unorm;
|
|
||||||
case VkFormat.R16G16B16A16SNorm:
|
|
||||||
return VkFormat.R16G16B16SNorm;
|
|
||||||
case VkFormat.R16G16B16A16Uint:
|
|
||||||
return VkFormat.R16G16B16Uint;
|
|
||||||
case VkFormat.R16G16B16A16Sint:
|
|
||||||
return VkFormat.R16G16B16Sint;
|
|
||||||
case VkFormat.R16G16B16A16Uscaled:
|
|
||||||
return VkFormat.R16G16B16Uscaled;
|
|
||||||
case VkFormat.R16G16B16A16Sscaled:
|
|
||||||
return VkFormat.R16G16B16Sscaled;
|
|
||||||
|
|
||||||
case VkFormat.R32G32Sfloat:
|
|
||||||
return VkFormat.R32Sfloat;
|
|
||||||
case VkFormat.R32G32Uint:
|
|
||||||
return VkFormat.R32Uint;
|
|
||||||
case VkFormat.R32G32Sint:
|
|
||||||
return VkFormat.R32Sint;
|
|
||||||
|
|
||||||
case VkFormat.R32G32B32Sfloat:
|
|
||||||
return VkFormat.R32G32Sfloat;
|
|
||||||
case VkFormat.R32G32B32Uint:
|
|
||||||
return VkFormat.R32G32Uint;
|
|
||||||
case VkFormat.R32G32B32Sint:
|
|
||||||
return VkFormat.R32G32Sint;
|
|
||||||
|
|
||||||
case VkFormat.R32G32B32A32Sfloat:
|
|
||||||
return VkFormat.R32G32B32Sfloat;
|
|
||||||
case VkFormat.R32G32B32A32Uint:
|
|
||||||
return VkFormat.R32G32B32Uint;
|
|
||||||
case VkFormat.R32G32B32A32Sint:
|
|
||||||
return VkFormat.R32G32B32Sint;
|
|
||||||
}
|
|
||||||
|
|
||||||
return format;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly Auto<DisposableImageView>[] _attachments;
|
private readonly Auto<DisposableImageView>[] _attachments;
|
||||||
private readonly TextureView[] _colors;
|
private readonly TextureView[] _colors;
|
||||||
private readonly TextureView _depthStencil;
|
private readonly TextureView _depthStencil;
|
||||||
private uint _validColorAttachments;
|
private readonly uint _validColorAttachments;
|
||||||
|
|
||||||
public uint Width { get; }
|
public uint Width { get; }
|
||||||
public uint Height { get; }
|
public uint Height { get; }
|
||||||
|
@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public uint AttachmentIntegerFormatMask { get; }
|
public uint AttachmentIntegerFormatMask { get; }
|
||||||
|
|
||||||
public int AttachmentsCount { get; }
|
public int AttachmentsCount { get; }
|
||||||
public int MaxColorAttachmentIndex => AttachmentIndices.Length > 0 ? AttachmentIndices[AttachmentIndices.Length - 1] : -1;
|
public int MaxColorAttachmentIndex => AttachmentIndices.Length > 0 ? AttachmentIndices[^1] : -1;
|
||||||
public bool HasDepthStencil { get; }
|
public bool HasDepthStencil { get; }
|
||||||
public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
||||||
|
|
||||||
|
@ -158,7 +158,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
return ComponentType.SignedInteger;
|
return ComponentType.SignedInteger;
|
||||||
}
|
}
|
||||||
else if (format.IsUint())
|
|
||||||
|
if (format.IsUint())
|
||||||
{
|
{
|
||||||
return ComponentType.UnsignedInteger;
|
return ComponentType.UnsignedInteger;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
attachments[i] = _attachments[i].Get(cbs).Value;
|
attachments[i] = _attachments[i].Get(cbs).Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
var framebufferCreateInfo = new FramebufferCreateInfo()
|
var framebufferCreateInfo = new FramebufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.FramebufferCreateInfo,
|
SType = StructureType.FramebufferCreateInfo,
|
||||||
RenderPass = renderPass.Get(cbs).Value,
|
RenderPass = renderPass.Get(cbs).Value,
|
||||||
|
@ -204,7 +205,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PAttachments = attachments,
|
PAttachments = attachments,
|
||||||
Width = Width,
|
Width = Width,
|
||||||
Height = Height,
|
Height = Height,
|
||||||
Layers = Layers
|
Layers = Layers,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CreateFramebuffer(_device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
api.CreateFramebuffer(_device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
NoTriangleFans = 1,
|
NoTriangleFans = 1,
|
||||||
NoPointMode = 1 << 1,
|
NoPointMode = 1 << 1,
|
||||||
No3DImageView = 1 << 2,
|
No3DImageView = 1 << 2,
|
||||||
NoLodBias = 1 << 3
|
NoLodBias = 1 << 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly struct HardwareCapabilities
|
readonly struct HardwareCapabilities
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
bool Equals(ref T other);
|
bool Equals(ref T other);
|
||||||
}
|
}
|
||||||
|
|
||||||
class HashTableSlim<K, V> where K : IRefEquatable<K>
|
class HashTableSlim<TKey, TValue> where TKey : IRefEquatable<TKey>
|
||||||
{
|
{
|
||||||
private const int TotalBuckets = 16; // Must be power of 2
|
private const int TotalBuckets = 16; // Must be power of 2
|
||||||
private const int TotalBucketsMask = TotalBuckets - 1;
|
private const int TotalBucketsMask = TotalBuckets - 1;
|
||||||
|
@ -16,13 +16,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private struct Entry
|
private struct Entry
|
||||||
{
|
{
|
||||||
public int Hash;
|
public int Hash;
|
||||||
public K Key;
|
public TKey Key;
|
||||||
public V Value;
|
public TValue Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Entry[][] _hashTable = new Entry[TotalBuckets][];
|
private readonly Entry[][] _hashTable = new Entry[TotalBuckets][];
|
||||||
|
|
||||||
public IEnumerable<K> Keys
|
public IEnumerable<TKey> Keys
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<V> Values
|
public IEnumerable<TValue> Values
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -56,13 +56,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(ref K key, V value)
|
public void Add(ref TKey key, TValue value)
|
||||||
{
|
{
|
||||||
var entry = new Entry()
|
var entry = new Entry
|
||||||
{
|
{
|
||||||
Hash = key.GetHashCode(),
|
Hash = key.GetHashCode(),
|
||||||
Key = key,
|
Key = key,
|
||||||
Value = value
|
Value = value,
|
||||||
};
|
};
|
||||||
|
|
||||||
int hashCode = key.GetHashCode();
|
int hashCode = key.GetHashCode();
|
||||||
|
@ -79,14 +79,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_hashTable[bucketIndex] = new Entry[]
|
_hashTable[bucketIndex] = new[]
|
||||||
{
|
{
|
||||||
entry
|
entry,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetValue(ref K key, out V value)
|
public bool TryGetValue(ref TKey key, out TValue value)
|
||||||
{
|
{
|
||||||
int hashCode = key.GetHashCode();
|
int hashCode = key.GetHashCode();
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,12 @@ using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||||
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
|
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
||||||
|
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||||
|
using StencilOp = Ryujinx.Graphics.GAL.StencilOp;
|
||||||
|
using Viewport = Ryujinx.Graphics.GAL.Viewport;
|
||||||
using VkFormat = Silk.NET.Vulkan.Format;
|
using VkFormat = Silk.NET.Vulkan.Format;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
|
@ -14,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Float,
|
Float,
|
||||||
SignedInteger,
|
SignedInteger,
|
||||||
UnsignedInteger
|
UnsignedInteger,
|
||||||
}
|
}
|
||||||
|
|
||||||
class HelperShader : IDisposable
|
class HelperShader : IDisposable
|
||||||
|
@ -52,8 +58,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline = new PipelineHelperShader(gd, device);
|
_pipeline = new PipelineHelperShader(gd, device);
|
||||||
_pipeline.Initialize();
|
_pipeline.Initialize();
|
||||||
|
|
||||||
_samplerLinear = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
_samplerLinear = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||||
_samplerNearest = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
_samplerNearest = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
||||||
|
|
||||||
var blitResourceLayout = new ResourceLayoutBuilder()
|
var blitResourceLayout = new ResourceLayoutBuilder()
|
||||||
.Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1)
|
.Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1)
|
||||||
|
@ -416,7 +422,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(
|
var rect = new Rectangle<float>(
|
||||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||||
|
@ -424,7 +430,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||||
|
|
||||||
viewports[0] = new GAL.Viewport(
|
viewports[0] = new Viewport(
|
||||||
rect,
|
rect,
|
||||||
ViewportSwizzle.PositiveX,
|
ViewportSwizzle.PositiveX,
|
||||||
ViewportSwizzle.PositiveY,
|
ViewportSwizzle.PositiveY,
|
||||||
|
@ -440,7 +446,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
if (dstIsDepthOrStencil)
|
if (dstIsDepthOrStencil)
|
||||||
{
|
{
|
||||||
_pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit);
|
_pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit);
|
||||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
|
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always));
|
||||||
}
|
}
|
||||||
else if (src.Info.Target.IsMultisample())
|
else if (src.Info.Target.IsMultisample())
|
||||||
{
|
{
|
||||||
|
@ -465,12 +471,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports, false);
|
||||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
_pipeline.Draw(4, 1, 0, 0);
|
_pipeline.Draw(4, 1, 0, 0);
|
||||||
|
|
||||||
if (dstIsDepthOrStencil)
|
if (dstIsDepthOrStencil)
|
||||||
{
|
{
|
||||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||||
}
|
}
|
||||||
|
|
||||||
_pipeline.Finish(gd, cbs);
|
_pipeline.Finish(gd, cbs);
|
||||||
|
@ -517,7 +523,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(
|
var rect = new Rectangle<float>(
|
||||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||||
|
@ -525,7 +531,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||||
|
|
||||||
viewports[0] = new GAL.Viewport(
|
viewports[0] = new Viewport(
|
||||||
rect,
|
rect,
|
||||||
ViewportSwizzle.PositiveX,
|
ViewportSwizzle.PositiveX,
|
||||||
ViewportSwizzle.PositiveY,
|
ViewportSwizzle.PositiveY,
|
||||||
|
@ -541,7 +547,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat);
|
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat);
|
||||||
_pipeline.SetScissors(scissors);
|
_pipeline.SetScissors(scissors);
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports, false);
|
||||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
||||||
|
|
||||||
|
@ -606,7 +612,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
if (isDepth)
|
if (isDepth)
|
||||||
{
|
{
|
||||||
_pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit);
|
_pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit);
|
||||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
|
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -618,7 +624,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (isDepth)
|
if (isDepth)
|
||||||
{
|
{
|
||||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -630,17 +636,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
return new StencilTestDescriptor(
|
return new StencilTestDescriptor(
|
||||||
enabled,
|
enabled,
|
||||||
GAL.CompareOp.Always,
|
CompareOp.Always,
|
||||||
GAL.StencilOp.Replace,
|
StencilOp.Replace,
|
||||||
GAL.StencilOp.Replace,
|
StencilOp.Replace,
|
||||||
GAL.StencilOp.Replace,
|
StencilOp.Replace,
|
||||||
0,
|
0,
|
||||||
0xff,
|
0xff,
|
||||||
0xff,
|
0xff,
|
||||||
GAL.CompareOp.Always,
|
CompareOp.Always,
|
||||||
GAL.StencilOp.Replace,
|
StencilOp.Replace,
|
||||||
GAL.StencilOp.Replace,
|
StencilOp.Replace,
|
||||||
GAL.StencilOp.Replace,
|
StencilOp.Replace,
|
||||||
0,
|
0,
|
||||||
0xff,
|
0xff,
|
||||||
0xff);
|
0xff);
|
||||||
|
@ -667,13 +673,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ClearColorBufferSize);
|
var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ClearColorBufferSize);
|
||||||
|
|
||||||
gd.BufferManager.SetData<float>(bufferHandle, 0, clearColor);
|
gd.BufferManager.SetData(bufferHandle, 0, clearColor);
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, ClearColorBufferSize)) });
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, ClearColorBufferSize)) });
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
viewports[0] = new GAL.Viewport(
|
viewports[0] = new Viewport(
|
||||||
new Rectangle<float>(0, 0, dstWidth, dstHeight),
|
new Rectangle<float>(0, 0, dstWidth, dstHeight),
|
||||||
ViewportSwizzle.PositiveX,
|
ViewportSwizzle.PositiveX,
|
||||||
ViewportSwizzle.PositiveY,
|
ViewportSwizzle.PositiveY,
|
||||||
|
@ -703,10 +709,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_pipeline.SetProgram(program);
|
_pipeline.SetProgram(program);
|
||||||
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat);
|
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat);
|
||||||
_pipeline.SetRenderTargetColorMasks(new uint[] { componentMask });
|
_pipeline.SetRenderTargetColorMasks(new[] { componentMask });
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports, false);
|
||||||
_pipeline.SetScissors(scissors);
|
_pipeline.SetScissors(scissors);
|
||||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
_pipeline.Draw(4, 1, 0, 0);
|
_pipeline.Draw(4, 1, 0, 0);
|
||||||
_pipeline.Finish();
|
_pipeline.Finish();
|
||||||
|
|
||||||
|
@ -748,7 +754,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(
|
var rect = new Rectangle<float>(
|
||||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||||
|
@ -756,7 +762,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||||
|
|
||||||
viewports[0] = new GAL.Viewport(
|
viewports[0] = new Viewport(
|
||||||
rect,
|
rect,
|
||||||
ViewportSwizzle.PositiveX,
|
ViewportSwizzle.PositiveX,
|
||||||
ViewportSwizzle.PositiveY,
|
ViewportSwizzle.PositiveY,
|
||||||
|
@ -769,13 +775,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
pipeline.SetProgram(_programColorBlit);
|
pipeline.SetProgram(_programColorBlit);
|
||||||
pipeline.SetViewports(viewports, false);
|
pipeline.SetViewports(viewports, false);
|
||||||
pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
pipeline.Draw(4, 1, 0, 0);
|
pipeline.Draw(4, 1, 0, 0);
|
||||||
|
|
||||||
gd.BufferManager.Delete(bufferHandle);
|
gd.BufferManager.Delete(bufferHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void ConvertI8ToI16(VulkanRenderer gd, CommandBufferScoped cbs, BufferHolder src, BufferHolder dst, int srcOffset, int size)
|
public void ConvertI8ToI16(VulkanRenderer gd, CommandBufferScoped cbs, BufferHolder src, BufferHolder dst, int srcOffset, int size)
|
||||||
{
|
{
|
||||||
ChangeStride(gd, cbs, src, dst, srcOffset, size, 1, 2);
|
ChangeStride(gd, cbs, src, dst, srcOffset, size, 1, 2);
|
||||||
}
|
}
|
||||||
|
@ -1093,11 +1099,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
// We can't use compute for this case because compute can't modify depth textures.
|
// We can't use compute for this case because compute can't modify depth textures.
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
var rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
||||||
|
|
||||||
viewports[0] = new GAL.Viewport(
|
viewports[0] = new Viewport(
|
||||||
rect,
|
rect,
|
||||||
ViewportSwizzle.PositiveX,
|
ViewportSwizzle.PositiveX,
|
||||||
ViewportSwizzle.PositiveY,
|
ViewportSwizzle.PositiveY,
|
||||||
|
@ -1112,7 +1118,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_pipeline.SetScissors(scissors);
|
_pipeline.SetScissors(scissors);
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports, false);
|
||||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
for (int z = 0; z < depth; z++)
|
for (int z = 0; z < depth; z++)
|
||||||
{
|
{
|
||||||
|
@ -1120,7 +1126,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||||
|
|
||||||
_pipeline.SetRenderTarget(
|
_pipeline.SetRenderTarget(
|
||||||
((TextureView)dstView).GetImageViewForAttachment(),
|
dstView.GetImageViewForAttachment(),
|
||||||
(uint)dst.Width,
|
(uint)dst.Width,
|
||||||
(uint)dst.Height,
|
(uint)dst.Height,
|
||||||
true,
|
true,
|
||||||
|
@ -1225,11 +1231,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_pipeline.SetCommandBuffer(cbs);
|
_pipeline.SetCommandBuffer(cbs);
|
||||||
|
|
||||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||||
|
|
||||||
var rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
var rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
||||||
|
|
||||||
viewports[0] = new GAL.Viewport(
|
viewports[0] = new Viewport(
|
||||||
rect,
|
rect,
|
||||||
ViewportSwizzle.PositiveX,
|
ViewportSwizzle.PositiveX,
|
||||||
ViewportSwizzle.PositiveY,
|
ViewportSwizzle.PositiveY,
|
||||||
|
@ -1245,7 +1251,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline.SetRenderTargetColorMasks(new uint[] { 0xf });
|
_pipeline.SetRenderTargetColorMasks(new uint[] { 0xf });
|
||||||
_pipeline.SetScissors(scissors);
|
_pipeline.SetScissors(scissors);
|
||||||
_pipeline.SetViewports(viewports, false);
|
_pipeline.SetViewports(viewports, false);
|
||||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
|
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
|
||||||
|
|
||||||
|
@ -1257,7 +1263,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||||
|
|
||||||
_pipeline.SetRenderTarget(
|
_pipeline.SetRenderTarget(
|
||||||
((TextureView)dstView).GetImageViewForAttachment(),
|
dstView.GetImageViewForAttachment(),
|
||||||
(uint)dst.Width,
|
(uint)dst.Width,
|
||||||
(uint)dst.Height,
|
(uint)dst.Height,
|
||||||
(uint)samples,
|
(uint)samples,
|
||||||
|
@ -1291,7 +1297,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, srcView, null);
|
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, srcView, null);
|
||||||
_pipeline.SetRenderTarget(
|
_pipeline.SetRenderTarget(
|
||||||
((TextureView)dstView).GetView(format).GetImageViewForAttachment(),
|
dstView.GetView(format).GetImageViewForAttachment(),
|
||||||
(uint)dst.Width,
|
(uint)dst.Width,
|
||||||
(uint)dst.Height,
|
(uint)dst.Height,
|
||||||
(uint)samples,
|
(uint)samples,
|
||||||
|
@ -1365,7 +1371,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
if (isDepth)
|
if (isDepth)
|
||||||
{
|
{
|
||||||
_pipeline.SetProgram(fromMS ? _programDepthDrawToNonMs : _programDepthDrawToMs);
|
_pipeline.SetProgram(fromMS ? _programDepthDrawToNonMs : _programDepthDrawToMs);
|
||||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
|
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1377,7 +1383,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (isDepth)
|
if (isDepth)
|
||||||
{
|
{
|
||||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1420,7 +1426,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return (samplesInXLog2, samplesInYLog2);
|
return (samplesInXLog2, samplesInYLog2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TextureView Create2DLayerView(TextureView from, int layer, int level, GAL.Format? format = null)
|
private static TextureView Create2DLayerView(TextureView from, int layer, int level, Format? format = null)
|
||||||
{
|
{
|
||||||
if (from.Info.Target == Target.Texture2D && level == 0 && (format == null || format.Value == from.Info.Format))
|
if (from.Info.Target == Target.Texture2D && level == 0 && (format == null || format.Value == from.Info.Format))
|
||||||
{
|
{
|
||||||
|
@ -1431,7 +1437,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
Target.Texture1DArray => Target.Texture1D,
|
Target.Texture1DArray => Target.Texture1D,
|
||||||
Target.Texture2DMultisampleArray => Target.Texture2DMultisample,
|
Target.Texture2DMultisampleArray => Target.Texture2DMultisample,
|
||||||
_ => Target.Texture2D
|
_ => Target.Texture2D,
|
||||||
};
|
};
|
||||||
|
|
||||||
var info = new TextureCreateInfo(
|
var info = new TextureCreateInfo(
|
||||||
|
@ -1454,56 +1460,56 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return from.CreateViewImpl(info, layer, level);
|
return from.CreateViewImpl(info, layer, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GAL.Format GetFormat(int bytesPerPixel)
|
private static Format GetFormat(int bytesPerPixel)
|
||||||
{
|
{
|
||||||
return bytesPerPixel switch
|
return bytesPerPixel switch
|
||||||
{
|
{
|
||||||
1 => GAL.Format.R8Uint,
|
1 => Format.R8Uint,
|
||||||
2 => GAL.Format.R16Uint,
|
2 => Format.R16Uint,
|
||||||
4 => GAL.Format.R32Uint,
|
4 => Format.R32Uint,
|
||||||
8 => GAL.Format.R32G32Uint,
|
8 => Format.R32G32Uint,
|
||||||
16 => GAL.Format.R32G32B32A32Uint,
|
16 => Format.R32G32B32A32Uint,
|
||||||
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}.")
|
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static GAL.Format GetFormat(int componentSize, int componentsCount)
|
private static Format GetFormat(int componentSize, int componentsCount)
|
||||||
{
|
{
|
||||||
if (componentSize == 1)
|
if (componentSize == 1)
|
||||||
{
|
{
|
||||||
return componentsCount switch
|
return componentsCount switch
|
||||||
{
|
{
|
||||||
1 => GAL.Format.R8Uint,
|
1 => Format.R8Uint,
|
||||||
2 => GAL.Format.R8G8Uint,
|
2 => Format.R8G8Uint,
|
||||||
4 => GAL.Format.R8G8B8A8Uint,
|
4 => Format.R8G8B8A8Uint,
|
||||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (componentSize == 2)
|
|
||||||
|
if (componentSize == 2)
|
||||||
{
|
{
|
||||||
return componentsCount switch
|
return componentsCount switch
|
||||||
{
|
{
|
||||||
1 => GAL.Format.R16Uint,
|
1 => Format.R16Uint,
|
||||||
2 => GAL.Format.R16G16Uint,
|
2 => Format.R16G16Uint,
|
||||||
4 => GAL.Format.R16G16B16A16Uint,
|
4 => Format.R16G16B16A16Uint,
|
||||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (componentSize == 4)
|
|
||||||
|
if (componentSize == 4)
|
||||||
{
|
{
|
||||||
return componentsCount switch
|
return componentsCount switch
|
||||||
{
|
{
|
||||||
1 => GAL.Format.R32Uint,
|
1 => Format.R32Uint,
|
||||||
2 => GAL.Format.R32G32Uint,
|
2 => Format.R32G32Uint,
|
||||||
4 => GAL.Format.R32G32B32A32Uint,
|
4 => Format.R32G32B32A32Uint,
|
||||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new ArgumentException($"Invalid component size {componentSize}.");
|
throw new ArgumentException($"Invalid component size {componentSize}.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void ConvertIndexBufferIndirect(
|
public void ConvertIndexBufferIndirect(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
|
@ -1524,7 +1530,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
// TODO: Support conversion with primitive restart enabled.
|
// TODO: Support conversion with primitive restart enabled.
|
||||||
|
|
||||||
BufferRange drawCountBufferAligned = new BufferRange(
|
BufferRange drawCountBufferAligned = new(
|
||||||
drawCountBuffer.Handle,
|
drawCountBuffer.Handle,
|
||||||
drawCountBuffer.Offset & ~(UniformBufferAlignment - 1),
|
drawCountBuffer.Offset & ~(UniformBufferAlignment - 1),
|
||||||
UniformBufferAlignment);
|
UniformBufferAlignment);
|
||||||
|
@ -1562,7 +1568,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
shaderParams[22] = indirectDataStride / 4;
|
shaderParams[22] = indirectDataStride / 4;
|
||||||
shaderParams[23] = srcIndirectBufferOffset / 4;
|
shaderParams[23] = srcIndirectBufferOffset / 4;
|
||||||
|
|
||||||
pattern.OffsetIndex.CopyTo(shaderParams.Slice(0, pattern.OffsetIndex.Length));
|
pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]);
|
||||||
|
|
||||||
var patternBufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize, out var patternBuffer);
|
var patternBufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize, out var patternBuffer);
|
||||||
var patternBufferAuto = patternBuffer.GetBuffer();
|
var patternBufferAuto = patternBuffer.GetBuffer();
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
internal class HostMemoryAllocator
|
internal class HostMemoryAllocator
|
||||||
{
|
{
|
||||||
private struct HostMemoryAllocation
|
private readonly struct HostMemoryAllocation
|
||||||
{
|
{
|
||||||
public readonly Auto<MemoryAllocation> Allocation;
|
public readonly Auto<MemoryAllocation> Allocation;
|
||||||
public readonly IntPtr Pointer;
|
public readonly IntPtr Pointer;
|
||||||
|
@ -33,8 +33,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
private List<HostMemoryAllocation> _allocations;
|
private readonly List<HostMemoryAllocation> _allocations;
|
||||||
private IntervalTree<ulong, HostMemoryAllocation> _allocationTree;
|
private readonly IntervalTree<ulong, HostMemoryAllocation> _allocationTree;
|
||||||
|
|
||||||
public HostMemoryAllocator(MemoryAllocator allocator, Vk api, ExtExternalMemoryHost hostMemoryApi, Device device)
|
public HostMemoryAllocator(MemoryAllocator allocator, Vk api, ExtExternalMemoryHost hostMemoryApi, Device device)
|
||||||
{
|
{
|
||||||
|
@ -100,19 +100,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportMemoryHostPointerInfoEXT importInfo = new ImportMemoryHostPointerInfoEXT()
|
ImportMemoryHostPointerInfoEXT importInfo = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.ImportMemoryHostPointerInfoExt,
|
SType = StructureType.ImportMemoryHostPointerInfoExt,
|
||||||
HandleType = ExternalMemoryHandleTypeFlags.HostAllocationBitExt,
|
HandleType = ExternalMemoryHandleTypeFlags.HostAllocationBitExt,
|
||||||
PHostPointer = (void*)pageAlignedPointer
|
PHostPointer = (void*)pageAlignedPointer,
|
||||||
};
|
};
|
||||||
|
|
||||||
var memoryAllocateInfo = new MemoryAllocateInfo()
|
var memoryAllocateInfo = new MemoryAllocateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryAllocateInfo,
|
SType = StructureType.MemoryAllocateInfo,
|
||||||
AllocationSize = pageAlignedSize,
|
AllocationSize = pageAlignedSize,
|
||||||
MemoryTypeIndex = (uint)memoryTypeIndex,
|
MemoryTypeIndex = (uint)memoryTypeIndex,
|
||||||
PNext = &importInfo
|
PNext = &importInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
Result result = _api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory);
|
Result result = _api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory);
|
||||||
|
|
|
@ -85,12 +85,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
value = _list[id];
|
value = _list[id];
|
||||||
return value != null;
|
return value != null;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
value = null;
|
value = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (ArgumentOutOfRangeException)
|
catch (ArgumentOutOfRangeException)
|
||||||
{
|
{
|
||||||
value = null;
|
value = null;
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public int IndexStride { get; }
|
public int IndexStride { get; }
|
||||||
public bool RepeatStart { get; }
|
public bool RepeatStart { get; }
|
||||||
|
|
||||||
private VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
private int _currentSize;
|
private int _currentSize;
|
||||||
private BufferHandle _repeatingBuffer;
|
private BufferHandle _repeatingBuffer;
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
using Silk.NET.Vulkan;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using IndexType = Silk.NET.Vulkan.IndexType;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
internal struct IndexBufferState
|
internal struct IndexBufferState
|
||||||
{
|
{
|
||||||
public static IndexBufferState Null => new IndexBufferState(GAL.BufferHandle.Null, 0, 0);
|
public static IndexBufferState Null => new(BufferHandle.Null, 0, 0);
|
||||||
|
|
||||||
private readonly int _offset;
|
private readonly int _offset;
|
||||||
private readonly int _size;
|
private readonly int _size;
|
||||||
private readonly IndexType _type;
|
private readonly IndexType _type;
|
||||||
|
|
||||||
private readonly GAL.BufferHandle _handle;
|
private readonly BufferHandle _handle;
|
||||||
private Auto<DisposableBuffer> _buffer;
|
private Auto<DisposableBuffer> _buffer;
|
||||||
|
|
||||||
public IndexBufferState(GAL.BufferHandle handle, int offset, int size, IndexType type)
|
public IndexBufferState(BufferHandle handle, int offset, int size, IndexType type)
|
||||||
{
|
{
|
||||||
_handle = handle;
|
_handle = handle;
|
||||||
_offset = offset;
|
_offset = offset;
|
||||||
|
@ -22,7 +23,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_buffer = null;
|
_buffer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexBufferState(GAL.BufferHandle handle, int offset, int size)
|
public IndexBufferState(BufferHandle handle, int offset, int size)
|
||||||
{
|
{
|
||||||
_handle = handle;
|
_handle = handle;
|
||||||
_offset = offset;
|
_offset = offset;
|
||||||
|
@ -97,8 +98,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public Auto<DisposableBuffer> BindConvertedIndexBufferIndirect(
|
public Auto<DisposableBuffer> BindConvertedIndexBufferIndirect(
|
||||||
VulkanRenderer gd,
|
VulkanRenderer gd,
|
||||||
CommandBufferScoped cbs,
|
CommandBufferScoped cbs,
|
||||||
GAL.BufferRange indirectBuffer,
|
BufferRange indirectBuffer,
|
||||||
GAL.BufferRange drawCountBuffer,
|
BufferRange drawCountBuffer,
|
||||||
IndexBufferPattern pattern,
|
IndexBufferPattern pattern,
|
||||||
bool hasDrawCount,
|
bool hasDrawCount,
|
||||||
int maxDrawCount,
|
int maxDrawCount,
|
||||||
|
@ -110,7 +111,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
(var indexBufferAuto, var indirectBufferAuto) = gd.BufferManager.GetBufferTopologyConversionIndirect(
|
(var indexBufferAuto, var indirectBufferAuto) = gd.BufferManager.GetBufferTopologyConversionIndirect(
|
||||||
gd,
|
gd,
|
||||||
cbs,
|
cbs,
|
||||||
new GAL.BufferRange(_handle, _offset, _size),
|
new BufferRange(_handle, _offset, _size),
|
||||||
indirectBuffer,
|
indirectBuffer,
|
||||||
drawCountBuffer,
|
drawCountBuffer,
|
||||||
pattern,
|
pattern,
|
||||||
|
@ -132,7 +133,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return indirectBufferAuto;
|
return indirectBufferAuto;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int GetIndexSize()
|
private readonly int GetIndexSize()
|
||||||
{
|
{
|
||||||
return _type switch
|
return _type switch
|
||||||
{
|
{
|
||||||
|
@ -142,7 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BoundEquals(Auto<DisposableBuffer> buffer)
|
public readonly bool BoundEquals(Auto<DisposableBuffer> buffer)
|
||||||
{
|
{
|
||||||
return _buffer == buffer;
|
return _buffer == buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
class MemoryAllocator : IDisposable
|
class MemoryAllocator : IDisposable
|
||||||
{
|
{
|
||||||
private ulong MaxDeviceMemoryUsageEstimate = 16UL * 1024 * 1024 * 1024;
|
private const ulong MaxDeviceMemoryUsageEstimate = 16UL * 1024 * 1024 * 1024;
|
||||||
|
|
||||||
private readonly Vk _api;
|
private readonly Vk _api;
|
||||||
private readonly VulkanPhysicalDevice _physicalDevice;
|
private readonly VulkanPhysicalDevice _physicalDevice;
|
||||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_physicalDevice = physicalDevice;
|
_physicalDevice = physicalDevice;
|
||||||
_device = device;
|
_device = device;
|
||||||
_blockLists = new List<MemoryAllocatorBlockList>();
|
_blockLists = new List<MemoryAllocatorBlockList>();
|
||||||
_blockAlignment = (int)Math.Min(int.MaxValue, MaxDeviceMemoryUsageEstimate / (ulong)_physicalDevice.PhysicalDeviceProperties.Limits.MaxMemoryAllocationCount);
|
_blockAlignment = (int)Math.Min(int.MaxValue, MaxDeviceMemoryUsageEstimate / _physicalDevice.PhysicalDeviceProperties.Limits.MaxMemoryAllocationCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryAllocation AllocateDeviceMemory(
|
public MemoryAllocation AllocateDeviceMemory(
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Size = size;
|
Size = size;
|
||||||
_freeRanges = new List<Range>
|
_freeRanges = new List<Range>
|
||||||
{
|
{
|
||||||
new Range(0, size)
|
new Range(0, size),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
var range = _freeRanges[i];
|
var range = _freeRanges[i];
|
||||||
|
|
||||||
ulong alignedOffset = BitUtils.AlignUp<ulong>(range.Offset, alignment);
|
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
|
||||||
ulong sizeDelta = alignedOffset - range.Offset;
|
ulong sizeDelta = alignedOffset - range.Offset;
|
||||||
ulong usableSize = range.Size - sizeDelta;
|
ulong usableSize = range.Size - sizeDelta;
|
||||||
|
|
||||||
|
@ -198,13 +198,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong blockAlignedSize = BitUtils.AlignUp<ulong>(size, (ulong)_blockAlignment);
|
ulong blockAlignedSize = BitUtils.AlignUp(size, (ulong)_blockAlignment);
|
||||||
|
|
||||||
var memoryAllocateInfo = new MemoryAllocateInfo()
|
var memoryAllocateInfo = new MemoryAllocateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryAllocateInfo,
|
SType = StructureType.MemoryAllocateInfo,
|
||||||
AllocationSize = blockAlignedSize,
|
AllocationSize = blockAlignedSize,
|
||||||
MemoryTypeIndex = (uint)MemoryTypeIndex
|
MemoryTypeIndex = (uint)MemoryTypeIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
_api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory).ThrowOnError();
|
_api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory).ThrowOnError();
|
||||||
|
@ -212,14 +212,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
IntPtr hostPointer = IntPtr.Zero;
|
IntPtr hostPointer = IntPtr.Zero;
|
||||||
|
|
||||||
if (map)
|
if (map)
|
||||||
{
|
|
||||||
unsafe
|
|
||||||
{
|
{
|
||||||
void* pointer = null;
|
void* pointer = null;
|
||||||
_api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError();
|
_api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError();
|
||||||
hostPointer = (IntPtr)pointer;
|
hostPointer = (IntPtr)pointer;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var newBlock = new Block(deviceMemory, hostPointer, blockAlignedSize);
|
var newBlock = new Block(deviceMemory, hostPointer, blockAlignedSize);
|
||||||
|
|
||||||
|
@ -238,10 +235,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (IntPtr)((nuint)(nint)block.HostPointer + offset);
|
return (IntPtr)((nuint)block.HostPointer + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Free(Block block, ulong offset, ulong size)
|
public void Free(Block block, ulong offset, ulong size)
|
||||||
{
|
{
|
||||||
block.Free(offset, size);
|
block.Free(offset, size);
|
||||||
|
|
||||||
|
@ -271,7 +268,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_blocks.Insert(index, block);
|
_blocks.Insert(index, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _blocks.Count; i++)
|
for (int i = 0; i < _blocks.Count; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||||
Error = 1,
|
Error = 1,
|
||||||
Warning = 2,
|
Warning = 2,
|
||||||
Info = 3,
|
Info = 3,
|
||||||
Debug = 4
|
Debug = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MVKConfigTraceVulkanCalls
|
enum MVKConfigTraceVulkanCalls
|
||||||
|
@ -17,14 +17,14 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||||
None = 0,
|
None = 0,
|
||||||
Enter = 1,
|
Enter = 1,
|
||||||
EnterExit = 2,
|
EnterExit = 2,
|
||||||
Duration = 3
|
Duration = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MVKConfigAutoGPUCaptureScope
|
enum MVKConfigAutoGPUCaptureScope
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
Device = 1,
|
Device = 1,
|
||||||
Frame = 2
|
Frame = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||||
All = 0x00000001,
|
All = 0x00000001,
|
||||||
MoltenVK = 0x00000002,
|
MoltenVK = 0x00000002,
|
||||||
WSI = 0x00000004,
|
WSI = 0x00000004,
|
||||||
Portability = 0x00000008
|
Portability = 0x00000008,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum MVKVkSemaphoreSupportStyle
|
enum MVKVkSemaphoreSupportStyle
|
||||||
|
@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE = 1,
|
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE = 1,
|
||||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS = 2,
|
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS = 2,
|
||||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK = 3,
|
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK = 3,
|
||||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_MAX_ENUM = 0x7FFFFFFF
|
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_MAX_ENUM = 0x7FFFFFFF,
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly struct Bool32
|
readonly struct Bool32
|
||||||
|
@ -60,7 +60,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator bool(Bool32 val) => val.Value == 1;
|
public static implicit operator bool(Bool32 val) => val.Value == 1;
|
||||||
public static implicit operator Bool32(bool val) => new Bool32(val);
|
public static implicit operator Bool32(bool val) => new(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
|
|
@ -8,10 +8,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class MultiFenceHolder
|
class MultiFenceHolder
|
||||||
{
|
{
|
||||||
private static int BufferUsageTrackingGranularity = 4096;
|
private static readonly int _bufferUsageTrackingGranularity = 4096;
|
||||||
|
|
||||||
private readonly FenceHolder[] _fences;
|
private readonly FenceHolder[] _fences;
|
||||||
private BufferUsageBitmap _bufferUsageBitmap;
|
private readonly BufferUsageBitmap _bufferUsageBitmap;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the multiple fence holder.
|
/// Creates a new instance of the multiple fence holder.
|
||||||
|
@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public MultiFenceHolder(int size)
|
public MultiFenceHolder(int size)
|
||||||
{
|
{
|
||||||
_fences = new FenceHolder[CommandBufferPool.MaxCommandBuffers];
|
_fences = new FenceHolder[CommandBufferPool.MaxCommandBuffers];
|
||||||
_bufferUsageBitmap = new BufferUsageBitmap(size, BufferUsageTrackingGranularity);
|
_bufferUsageBitmap = new BufferUsageBitmap(size, _bufferUsageTrackingGranularity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -189,11 +189,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (hasTimeout)
|
if (hasTimeout)
|
||||||
{
|
{
|
||||||
signaled = FenceHelper.AllSignaled(api, device, fences.Slice(0, fenceCount), timeout);
|
signaled = FenceHelper.AllSignaled(api, device, fences[..fenceCount], timeout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FenceHelper.WaitAllIndefinitely(api, device, fences.Slice(0, fenceCount));
|
FenceHelper.WaitAllIndefinitely(api, device, fences[..fenceCount]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < fenceCount; i++)
|
for (int i = 0; i < fenceCount; i++)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using System;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
internal class PersistentFlushBuffer : IDisposable
|
internal class PersistentFlushBuffer : IDisposable
|
||||||
{
|
{
|
||||||
private VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
|
|
||||||
private BufferHolder _flushStorage;
|
private BufferHolder _flushStorage;
|
||||||
|
|
||||||
|
@ -19,10 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (flushStorage == null || size > _flushStorage.Size)
|
if (flushStorage == null || size > _flushStorage.Size)
|
||||||
{
|
{
|
||||||
if (flushStorage != null)
|
flushStorage?.Dispose();
|
||||||
{
|
|
||||||
flushStorage.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
flushStorage = _gd.BufferManager.Create(_gd, size);
|
flushStorage = _gd.BufferManager.Create(_gd, size);
|
||||||
_flushStorage = flushStorage;
|
_flushStorage = flushStorage;
|
||||||
|
@ -59,7 +57,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size)
|
public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size)
|
||||||
{
|
{
|
||||||
GAL.TextureCreateInfo info = view.Info;
|
TextureCreateInfo info = view.Info;
|
||||||
|
|
||||||
var flushStorage = ResizeIfNeeded(size);
|
var flushStorage = ResizeIfNeeded(size);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.GAL;
|
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
@ -7,6 +6,13 @@ 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 CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||||
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
|
using FrontFace = Ryujinx.Graphics.GAL.FrontFace;
|
||||||
|
using IndexType = Ryujinx.Graphics.GAL.IndexType;
|
||||||
|
using PolygonMode = Ryujinx.Graphics.GAL.PolygonMode;
|
||||||
|
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
||||||
|
using Viewport = Ryujinx.Graphics.GAL.Viewport;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -28,7 +34,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
protected PipelineDynamicState DynamicState;
|
protected PipelineDynamicState DynamicState;
|
||||||
private PipelineState _newState;
|
private PipelineState _newState;
|
||||||
private bool _stateDirty;
|
private bool _stateDirty;
|
||||||
private GAL.PrimitiveTopology _topology;
|
private PrimitiveTopology _topology;
|
||||||
|
|
||||||
private ulong _currentPipelineHandle;
|
private ulong _currentPipelineHandle;
|
||||||
|
|
||||||
|
@ -44,7 +50,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private ShaderCollection _program;
|
private ShaderCollection _program;
|
||||||
|
|
||||||
private Vector4<float>[] _renderScale = new Vector4<float>[73];
|
private readonly Vector4<float>[] _renderScale = new Vector4<float>[73];
|
||||||
private int _fragmentScaleCount;
|
private int _fragmentScaleCount;
|
||||||
|
|
||||||
protected FramebufferParams FramebufferParams;
|
protected FramebufferParams FramebufferParams;
|
||||||
|
@ -78,7 +84,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private bool _tfEnabled;
|
private bool _tfEnabled;
|
||||||
private bool _tfActive;
|
private bool _tfActive;
|
||||||
|
|
||||||
private PipelineColorBlendAttachmentState[] _storedBlend;
|
private readonly PipelineColorBlendAttachmentState[] _storedBlend;
|
||||||
|
|
||||||
private ulong _drawCountSinceBarrier;
|
private ulong _drawCountSinceBarrier;
|
||||||
public ulong DrawCount { get; private set; }
|
public ulong DrawCount { get; private set; }
|
||||||
|
@ -91,9 +97,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
AutoFlush = new AutoFlushCounter(gd);
|
AutoFlush = new AutoFlushCounter(gd);
|
||||||
|
|
||||||
var pipelineCacheCreateInfo = new PipelineCacheCreateInfo()
|
var pipelineCacheCreateInfo = new PipelineCacheCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineCacheCreateInfo
|
SType = StructureType.PipelineCacheCreateInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreatePipelineCache(device, pipelineCacheCreateInfo, null, out PipelineCache).ThrowOnError();
|
gd.Api.CreatePipelineCache(device, pipelineCacheCreateInfo, null, out PipelineCache).ThrowOnError();
|
||||||
|
@ -108,7 +114,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
using var emptyVb = gd.BufferManager.Create(gd, EmptyVbSize);
|
using var 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, 0);
|
_vertexBuffers[0] = new VertexBufferState(emptyVb.GetBuffer(), 0, 0, EmptyVbSize);
|
||||||
_vertexBuffersDirty = ulong.MaxValue >> (64 - _vertexBuffers.Length);
|
_vertexBuffersDirty = ulong.MaxValue >> (64 - _vertexBuffers.Length);
|
||||||
|
|
||||||
ClearScissor = new Rectangle<int>(0, 0, 0xffff, 0xffff);
|
ClearScissor = new Rectangle<int>(0, 0, 0xffff, 0xffff);
|
||||||
|
@ -146,11 +152,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
MemoryBarrier memoryBarrier = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryBarrier,
|
SType = StructureType.MemoryBarrier,
|
||||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||||
};
|
};
|
||||||
|
|
||||||
Gd.Api.CmdPipelineBarrier(
|
Gd.Api.CmdPipelineBarrier(
|
||||||
|
@ -168,11 +174,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void ComputeBarrier()
|
public void ComputeBarrier()
|
||||||
{
|
{
|
||||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
MemoryBarrier memoryBarrier = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryBarrier,
|
SType = StructureType.MemoryBarrier,
|
||||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||||
};
|
};
|
||||||
|
|
||||||
Gd.Api.CmdPipelineBarrier(
|
Gd.Api.CmdPipelineBarrier(
|
||||||
|
@ -188,7 +194,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ReadOnlySpan<ImageMemoryBarrier>.Empty);
|
ReadOnlySpan<ImageMemoryBarrier>.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginTransformFeedback(GAL.PrimitiveTopology topology)
|
public void BeginTransformFeedback(PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
_tfEnabled = true;
|
_tfEnabled = true;
|
||||||
}
|
}
|
||||||
|
@ -281,11 +287,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public unsafe void CommandBufferBarrier()
|
public unsafe void CommandBufferBarrier()
|
||||||
{
|
{
|
||||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
MemoryBarrier memoryBarrier = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryBarrier,
|
SType = StructureType.MemoryBarrier,
|
||||||
SrcAccessMask = BufferHolder.DefaultAccessFlags,
|
SrcAccessMask = BufferHolder.DefaultAccessFlags,
|
||||||
DstAccessMask = AccessFlags.IndirectCommandReadBit
|
DstAccessMask = AccessFlags.IndirectCommandReadBit,
|
||||||
};
|
};
|
||||||
|
|
||||||
Gd.Api.CmdPipelineBarrier(
|
Gd.Api.CmdPipelineBarrier(
|
||||||
|
@ -374,10 +380,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
IndexBufferPattern pattern = _topology switch
|
IndexBufferPattern pattern = _topology switch
|
||||||
{
|
{
|
||||||
GAL.PrimitiveTopology.Quads => QuadsToTrisPattern,
|
PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||||
GAL.PrimitiveTopology.TriangleFan or
|
PrimitiveTopology.TriangleFan or
|
||||||
GAL.PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}")
|
_ => throw new NotSupportedException($"Unsupported topology: {_topology}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount);
|
BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount);
|
||||||
|
@ -406,10 +412,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
pattern = _topology switch
|
pattern = _topology switch
|
||||||
{
|
{
|
||||||
GAL.PrimitiveTopology.Quads => QuadsToTrisPattern,
|
PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||||
GAL.PrimitiveTopology.TriangleFan or
|
PrimitiveTopology.TriangleFan or
|
||||||
GAL.PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}")
|
_ => throw new NotSupportedException($"Unsupported topology: {_topology}"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,7 +724,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return CommandBuffer.Handle == cb.Handle;
|
return CommandBuffer.Handle == cb.Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAlphaTest(bool enable, float reference, GAL.CompareOp op)
|
public void SetAlphaTest(bool enable, float reference, CompareOp op)
|
||||||
{
|
{
|
||||||
// This is currently handled using shader specialization, as Vulkan does not support alpha test.
|
// This is currently handled using shader specialization, as Vulkan does not support alpha test.
|
||||||
// In the future, we may want to use this to write the reference value into the support buffer,
|
// In the future, we may want to use this to write the reference value into the support buffer,
|
||||||
|
@ -847,13 +853,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFrontFace(GAL.FrontFace frontFace)
|
public void SetFrontFace(FrontFace frontFace)
|
||||||
{
|
{
|
||||||
_newState.FrontFace = frontFace.Convert();
|
_newState.FrontFace = frontFace.Convert();
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetImage(int binding, ITexture image, GAL.Format imageFormat)
|
public void SetImage(int binding, ITexture image, Format imageFormat)
|
||||||
{
|
{
|
||||||
_descriptorSetUpdater.SetImage(binding, image, imageFormat);
|
_descriptorSetUpdater.SetImage(binding, image, imageFormat);
|
||||||
}
|
}
|
||||||
|
@ -863,7 +869,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_descriptorSetUpdater.SetImage(binding, image);
|
_descriptorSetUpdater.SetImage(binding, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetIndexBuffer(BufferRange buffer, GAL.IndexType type)
|
public void SetIndexBuffer(BufferRange buffer, IndexType type)
|
||||||
{
|
{
|
||||||
if (buffer.Handle != BufferHandle.Null)
|
if (buffer.Handle != BufferHandle.Null)
|
||||||
{
|
{
|
||||||
|
@ -897,12 +903,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetOrigin(Origin origin)
|
public void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
||||||
{
|
|
||||||
// TODO.
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
|
||||||
{
|
{
|
||||||
_newState.PatchControlPoints = (uint)vertices;
|
_newState.PatchControlPoints = (uint)vertices;
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
|
@ -910,15 +911,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// TODO: Default levels (likely needs emulation on shaders?)
|
// TODO: Default levels (likely needs emulation on shaders?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1822 // Mark member as static
|
||||||
public void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
|
public void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
|
||||||
{
|
{
|
||||||
// TODO.
|
// TODO.
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPolygonMode(GAL.PolygonMode frontMode, GAL.PolygonMode backMode)
|
public void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode)
|
||||||
{
|
{
|
||||||
// TODO.
|
// TODO.
|
||||||
}
|
}
|
||||||
|
#pragma warning restore CA1822
|
||||||
|
|
||||||
public void SetPrimitiveRestart(bool enable, int index)
|
public void SetPrimitiveRestart(bool enable, int index)
|
||||||
{
|
{
|
||||||
|
@ -927,7 +930,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPrimitiveTopology(GAL.PrimitiveTopology topology)
|
public void SetPrimitiveTopology(PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
_topology = topology;
|
_topology = topology;
|
||||||
|
|
||||||
|
@ -950,7 +953,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_newState.PipelineLayout = internalProgram.PipelineLayout;
|
_newState.PipelineLayout = internalProgram.PipelineLayout;
|
||||||
_newState.StagesCount = (uint)stages.Length;
|
_newState.StagesCount = (uint)stages.Length;
|
||||||
|
|
||||||
stages.CopyTo(_newState.Stages.AsSpan().Slice(0, stages.Length));
|
stages.CopyTo(_newState.Stages.AsSpan()[..stages.Length]);
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
|
|
||||||
|
@ -1149,10 +1152,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_descriptorSetUpdater.SetUniformBuffers(CommandBuffer, buffers);
|
_descriptorSetUpdater.SetUniformBuffers(CommandBuffer, buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CA1822 // Mark member as static
|
||||||
public void SetUserClipDistance(int index, bool enableClip)
|
public void SetUserClipDistance(int index, bool enableClip)
|
||||||
{
|
{
|
||||||
// TODO.
|
// TODO.
|
||||||
}
|
}
|
||||||
|
#pragma warning restore CA1822
|
||||||
|
|
||||||
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
||||||
{
|
{
|
||||||
|
@ -1298,7 +1303,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetViewports(ReadOnlySpan<GAL.Viewport> viewports, bool disableTransform)
|
public void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform)
|
||||||
{
|
{
|
||||||
int maxViewports = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1;
|
int maxViewports = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1;
|
||||||
int count = Math.Min(maxViewports, viewports.Length);
|
int count = Math.Min(maxViewports, viewports.Length);
|
||||||
|
@ -1332,7 +1337,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
X = scale * 2f / viewports[0].Region.Width,
|
X = scale * 2f / viewports[0].Region.Width,
|
||||||
Y = scale * 2f / viewports[0].Region.Height,
|
Y = scale * 2f / viewports[0].Region.Height,
|
||||||
Z = 1,
|
Z = 1,
|
||||||
W = disableTransformF
|
W = disableTransformF,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1361,11 +1366,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public unsafe void TextureBarrier()
|
public unsafe void TextureBarrier()
|
||||||
{
|
{
|
||||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
MemoryBarrier memoryBarrier = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.MemoryBarrier,
|
SType = StructureType.MemoryBarrier,
|
||||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||||
};
|
};
|
||||||
|
|
||||||
Gd.Api.CmdPipelineBarrier(
|
Gd.Api.CmdPipelineBarrier(
|
||||||
|
@ -1433,7 +1438,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// Just try to remove duplicate attachments.
|
// Just try to remove duplicate attachments.
|
||||||
// Save a copy of the array to rebind when mask changes.
|
// Save a copy of the array to rebind when mask changes.
|
||||||
|
|
||||||
void maskOut()
|
void MaskOut()
|
||||||
{
|
{
|
||||||
if (!_framebufferUsingColorWriteMask)
|
if (!_framebufferUsingColorWriteMask)
|
||||||
{
|
{
|
||||||
|
@ -1467,12 +1472,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
if (vkBlend.ColorWriteMask == 0)
|
if (vkBlend.ColorWriteMask == 0)
|
||||||
{
|
{
|
||||||
colors[i] = null;
|
colors[i] = null;
|
||||||
maskOut();
|
MaskOut();
|
||||||
}
|
}
|
||||||
else if (vkBlend2.ColorWriteMask == 0)
|
else if (vkBlend2.ColorWriteMask == 0)
|
||||||
{
|
{
|
||||||
colors[j] = null;
|
colors[j] = null;
|
||||||
maskOut();
|
MaskOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1505,9 +1510,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
AttachmentDescription[] attachmentDescs = null;
|
AttachmentDescription[] attachmentDescs = null;
|
||||||
|
|
||||||
var subpass = new SubpassDescription()
|
var subpass = new SubpassDescription
|
||||||
{
|
{
|
||||||
PipelineBindPoint = PipelineBindPoint.Graphics
|
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||||
};
|
};
|
||||||
|
|
||||||
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
||||||
|
@ -1572,7 +1577,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||||
{
|
{
|
||||||
var renderPassCreateInfo = new RenderPassCreateInfo()
|
var renderPassCreateInfo = new RenderPassCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassCreateInfo,
|
SType = StructureType.RenderPassCreateInfo,
|
||||||
PAttachments = pAttachmentDescs,
|
PAttachments = pAttachmentDescs,
|
||||||
|
@ -1580,7 +1585,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PSubpasses = &subpass,
|
PSubpasses = &subpass,
|
||||||
SubpassCount = 1,
|
SubpassCount = 1,
|
||||||
PDependencies = &subpassDependency,
|
PDependencies = &subpassDependency,
|
||||||
DependencyCount = 1
|
DependencyCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
Gd.Api.CreateRenderPass(Device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
Gd.Api.CreateRenderPass(Device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
||||||
|
@ -1688,14 +1693,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var renderArea = new Rect2D(null, new Extent2D(FramebufferParams.Width, FramebufferParams.Height));
|
var renderArea = new Rect2D(null, new Extent2D(FramebufferParams.Width, FramebufferParams.Height));
|
||||||
var clearValue = new ClearValue();
|
var clearValue = new ClearValue();
|
||||||
|
|
||||||
var renderPassBeginInfo = new RenderPassBeginInfo()
|
var renderPassBeginInfo = new RenderPassBeginInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassBeginInfo,
|
SType = StructureType.RenderPassBeginInfo,
|
||||||
RenderPass = _renderPass.Get(Cbs).Value,
|
RenderPass = _renderPass.Get(Cbs).Value,
|
||||||
Framebuffer = _framebuffer.Get(Cbs).Value,
|
Framebuffer = _framebuffer.Get(Cbs).Value,
|
||||||
RenderArea = renderArea,
|
RenderArea = renderArea,
|
||||||
PClearValues = &clearValue,
|
PClearValues = &clearValue,
|
||||||
ClearValueCount = 1
|
ClearValueCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
Gd.Api.CmdBeginRenderPass(CommandBuffer, renderPassBeginInfo, SubpassContents.Inline);
|
Gd.Api.CmdBeginRenderPass(CommandBuffer, renderPassBeginInfo, SubpassContents.Inline);
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
using Format = Silk.NET.Vulkan.Format;
|
||||||
|
using PolygonMode = Silk.NET.Vulkan.PolygonMode;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -16,15 +18,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
AttachmentDescription[] attachmentDescs = null;
|
AttachmentDescription[] attachmentDescs = null;
|
||||||
|
|
||||||
var subpass = new SubpassDescription()
|
var subpass = new SubpassDescription
|
||||||
{
|
{
|
||||||
PipelineBindPoint = PipelineBindPoint.Graphics
|
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||||
};
|
};
|
||||||
|
|
||||||
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
||||||
|
|
||||||
Span<int> attachmentIndices = stackalloc int[MaxAttachments];
|
Span<int> attachmentIndices = stackalloc int[MaxAttachments];
|
||||||
Span<Silk.NET.Vulkan.Format> attachmentFormats = stackalloc Silk.NET.Vulkan.Format[MaxAttachments];
|
Span<Format> attachmentFormats = stackalloc Format[MaxAttachments];
|
||||||
|
|
||||||
int attachmentCount = 0;
|
int attachmentCount = 0;
|
||||||
int colorCount = 0;
|
int colorCount = 0;
|
||||||
|
@ -106,7 +108,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||||
{
|
{
|
||||||
var renderPassCreateInfo = new RenderPassCreateInfo()
|
var renderPassCreateInfo = new RenderPassCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassCreateInfo,
|
SType = StructureType.RenderPassCreateInfo,
|
||||||
PAttachments = pAttachmentDescs,
|
PAttachments = pAttachmentDescs,
|
||||||
|
@ -114,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PSubpasses = &subpass,
|
PSubpasses = &subpass,
|
||||||
SubpassCount = 1,
|
SubpassCount = 1,
|
||||||
PDependencies = &subpassDependency,
|
PDependencies = &subpassDependency,
|
||||||
DependencyCount = 1
|
DependencyCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateRenderPass(device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
gd.Api.CreateRenderPass(device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
||||||
|
@ -151,7 +153,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public static PipelineState ToVulkanPipelineState(this ProgramPipelineState state, VulkanRenderer gd)
|
public static PipelineState ToVulkanPipelineState(this ProgramPipelineState state, VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
PipelineState pipeline = new PipelineState();
|
PipelineState pipeline = new();
|
||||||
pipeline.Initialize();
|
pipeline.Initialize();
|
||||||
|
|
||||||
// It is assumed that Dynamic State is enabled when this conversion is used.
|
// It is assumed that Dynamic State is enabled when this conversion is used.
|
||||||
|
@ -178,7 +180,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
pipeline.MaxDepthBounds = 0f; // Not implemented.
|
pipeline.MaxDepthBounds = 0f; // Not implemented.
|
||||||
|
|
||||||
pipeline.PatchControlPoints = state.PatchControlPoints;
|
pipeline.PatchControlPoints = state.PatchControlPoints;
|
||||||
pipeline.PolygonMode = Silk.NET.Vulkan.PolygonMode.Fill; // Not implemented.
|
pipeline.PolygonMode = PolygonMode.Fill; // Not implemented.
|
||||||
pipeline.PrimitiveRestartEnable = state.PrimitiveRestartEnable;
|
pipeline.PrimitiveRestartEnable = state.PrimitiveRestartEnable;
|
||||||
pipeline.RasterizerDiscardEnable = state.RasterizerDiscard;
|
pipeline.RasterizerDiscardEnable = state.RasterizerDiscard;
|
||||||
pipeline.SamplesCount = (uint)state.SamplesCount;
|
pipeline.SamplesCount = (uint)state.SamplesCount;
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Scissor = 1 << 2,
|
Scissor = 1 << 2,
|
||||||
Stencil = 1 << 3,
|
Stencil = 1 << 3,
|
||||||
Viewport = 1 << 4,
|
Viewport = 1 << 4,
|
||||||
All = Blend | DepthBias | Scissor | Stencil | Viewport
|
All = Blend | DepthBias | Scissor | Stencil | Viewport,
|
||||||
}
|
}
|
||||||
|
|
||||||
private DirtyFlags _dirty;
|
private DirtyFlags _dirty;
|
||||||
|
@ -139,7 +139,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan());
|
api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordDepthBias(Vk api, CommandBuffer commandBuffer)
|
private readonly void RecordDepthBias(Vk api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
|
api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
api.CmdSetScissor(commandBuffer, 0, (uint)ScissorsCount, _scissors.AsSpan());
|
api.CmdSetScissor(commandBuffer, 0, (uint)ScissorsCount, _scissors.AsSpan());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RecordStencilMasks(Vk api, CommandBuffer commandBuffer)
|
private readonly void RecordStencilMasks(Vk api, CommandBuffer commandBuffer)
|
||||||
{
|
{
|
||||||
api.CmdSetStencilCompareMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backCompareMask);
|
api.CmdSetStencilCompareMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backCompareMask);
|
||||||
api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backWriteMask);
|
api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backWriteMask);
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private ulong _byteWeight;
|
private ulong _byteWeight;
|
||||||
|
|
||||||
private List<BufferHolder> _backingSwaps;
|
private readonly List<BufferHolder> _backingSwaps;
|
||||||
|
|
||||||
public PipelineFull(VulkanRenderer gd, Device device) : base(gd, device)
|
public PipelineFull(VulkanRenderer gd, Device device) : base(gd, device)
|
||||||
{
|
{
|
||||||
|
@ -116,15 +116,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (Gd.Capabilities.SupportsConditionalRendering)
|
if (Gd.Capabilities.SupportsConditionalRendering)
|
||||||
{
|
{
|
||||||
var buffer = evt.GetBuffer().Get(Cbs, 0, sizeof(long)).Value;
|
// var buffer = evt.GetBuffer().Get(Cbs, 0, sizeof(long)).Value;
|
||||||
var flags = isEqual ? ConditionalRenderingFlagsEXT.InvertedBitExt : 0;
|
// var flags = isEqual ? ConditionalRenderingFlagsEXT.InvertedBitExt : 0;
|
||||||
|
|
||||||
var conditionalRenderingBeginInfo = new ConditionalRenderingBeginInfoEXT()
|
// var conditionalRenderingBeginInfo = new ConditionalRenderingBeginInfoEXT
|
||||||
{
|
// {
|
||||||
SType = StructureType.ConditionalRenderingBeginInfoExt,
|
// SType = StructureType.ConditionalRenderingBeginInfoExt,
|
||||||
Buffer = buffer,
|
// Buffer = buffer,
|
||||||
Flags = flags
|
// Flags = flags,
|
||||||
};
|
// };
|
||||||
|
|
||||||
// Gd.ConditionalRenderingApi.CmdBeginConditionalRendering(CommandBuffer, conditionalRenderingBeginInfo);
|
// Gd.ConditionalRenderingApi.CmdBeginConditionalRendering(CommandBuffer, conditionalRenderingBeginInfo);
|
||||||
}
|
}
|
||||||
|
@ -156,10 +156,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public CommandBufferScoped GetPreloadCommandBuffer()
|
public CommandBufferScoped GetPreloadCommandBuffer()
|
||||||
{
|
{
|
||||||
if (PreloadCbs == null)
|
PreloadCbs ??= Gd.CommandBufferPool.Rent();
|
||||||
{
|
|
||||||
PreloadCbs = Gd.CommandBufferPool.Rent();
|
|
||||||
}
|
|
||||||
|
|
||||||
return PreloadCbs.Value;
|
return PreloadCbs.Value;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +189,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
CommandBufferScoped? cbs = null;
|
CommandBufferScoped? cbs = null;
|
||||||
|
|
||||||
_backingSwaps.RemoveAll((holder) => holder.TryBackingSwap(ref cbs));
|
_backingSwaps.RemoveAll(holder => holder.TryBackingSwap(ref cbs));
|
||||||
|
|
||||||
cbs?.Dispose();
|
cbs?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
HashCode hasher = new HashCode();
|
HashCode hasher = new();
|
||||||
|
|
||||||
if (SetDescriptors != null)
|
if (SetDescriptors != null)
|
||||||
{
|
{
|
||||||
|
@ -83,10 +83,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
var key = new PlceKey(setDescriptors, usePushDescriptors);
|
var 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual unsafe void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,23 +45,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
stages = activeStages;
|
stages = activeStages;
|
||||||
}
|
}
|
||||||
|
|
||||||
layoutBindings[descIndex] = new DescriptorSetLayoutBinding()
|
layoutBindings[descIndex] = new DescriptorSetLayoutBinding
|
||||||
{
|
{
|
||||||
Binding = (uint)descriptor.Binding,
|
Binding = (uint)descriptor.Binding,
|
||||||
DescriptorType = descriptor.Type.Convert(),
|
DescriptorType = descriptor.Type.Convert(),
|
||||||
DescriptorCount = (uint)descriptor.Count,
|
DescriptorCount = (uint)descriptor.Count,
|
||||||
StageFlags = stages.Convert()
|
StageFlags = stages.Convert(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed (DescriptorSetLayoutBinding* pLayoutBindings = layoutBindings)
|
fixed (DescriptorSetLayoutBinding* pLayoutBindings = layoutBindings)
|
||||||
{
|
{
|
||||||
var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
|
var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DescriptorSetLayoutCreateInfo,
|
SType = StructureType.DescriptorSetLayoutCreateInfo,
|
||||||
PBindings = pLayoutBindings,
|
PBindings = pLayoutBindings,
|
||||||
BindingCount = (uint)layoutBindings.Length,
|
BindingCount = (uint)layoutBindings.Length,
|
||||||
Flags = usePushDescriptors && setIndex == 0 ? DescriptorSetLayoutCreateFlags.PushDescriptorBitKhr : DescriptorSetLayoutCreateFlags.None
|
Flags = usePushDescriptors && setIndex == 0 ? DescriptorSetLayoutCreateFlags.PushDescriptorBitKhr : DescriptorSetLayoutCreateFlags.None,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateDescriptorSetLayout(device, descriptorSetLayoutCreateInfo, null, out layouts[setIndex]).ThrowOnError();
|
gd.Api.CreateDescriptorSetLayout(device, descriptorSetLayoutCreateInfo, null, out layouts[setIndex]).ThrowOnError();
|
||||||
|
@ -72,11 +72,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
fixed (DescriptorSetLayout* pLayouts = layouts)
|
fixed (DescriptorSetLayout* pLayouts = layouts)
|
||||||
{
|
{
|
||||||
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
|
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineLayoutCreateInfo,
|
SType = StructureType.PipelineLayoutCreateInfo,
|
||||||
PSetLayouts = pLayouts,
|
PSetLayouts = pLayouts,
|
||||||
SetLayoutCount = (uint)layouts.Length
|
SetLayoutCount = (uint)layouts.Length,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
|
gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
|
||||||
|
|
|
@ -13,301 +13,301 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public float LineWidth
|
public float LineWidth
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id0 >> 0) & 0xFFFFFFFF));
|
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id0 >> 0) & 0xFFFFFFFF));
|
||||||
set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float DepthBiasClamp
|
public float DepthBiasClamp
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id0 >> 32) & 0xFFFFFFFF));
|
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id0 >> 32) & 0xFFFFFFFF));
|
||||||
set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float DepthBiasConstantFactor
|
public float DepthBiasConstantFactor
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id1 >> 0) & 0xFFFFFFFF));
|
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id1 >> 0) & 0xFFFFFFFF));
|
||||||
set => Internal.Id1 = (Internal.Id1 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
set => Internal.Id1 = (Internal.Id1 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float DepthBiasSlopeFactor
|
public float DepthBiasSlopeFactor
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id1 >> 32) & 0xFFFFFFFF));
|
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id1 >> 32) & 0xFFFFFFFF));
|
||||||
set => Internal.Id1 = (Internal.Id1 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
set => Internal.Id1 = (Internal.Id1 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint StencilFrontCompareMask
|
public uint StencilFrontCompareMask
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id2 >> 0) & 0xFFFFFFFF);
|
readonly get => (uint)((Internal.Id2 >> 0) & 0xFFFFFFFF);
|
||||||
set => Internal.Id2 = (Internal.Id2 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
set => Internal.Id2 = (Internal.Id2 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint StencilFrontWriteMask
|
public uint StencilFrontWriteMask
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id2 >> 32) & 0xFFFFFFFF);
|
readonly get => (uint)((Internal.Id2 >> 32) & 0xFFFFFFFF);
|
||||||
set => Internal.Id2 = (Internal.Id2 & 0xFFFFFFFF) | ((ulong)value << 32);
|
set => Internal.Id2 = (Internal.Id2 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint StencilFrontReference
|
public uint StencilFrontReference
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id3 >> 0) & 0xFFFFFFFF);
|
readonly get => (uint)((Internal.Id3 >> 0) & 0xFFFFFFFF);
|
||||||
set => Internal.Id3 = (Internal.Id3 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
set => Internal.Id3 = (Internal.Id3 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint StencilBackCompareMask
|
public uint StencilBackCompareMask
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id3 >> 32) & 0xFFFFFFFF);
|
readonly get => (uint)((Internal.Id3 >> 32) & 0xFFFFFFFF);
|
||||||
set => Internal.Id3 = (Internal.Id3 & 0xFFFFFFFF) | ((ulong)value << 32);
|
set => Internal.Id3 = (Internal.Id3 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint StencilBackWriteMask
|
public uint StencilBackWriteMask
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id4 >> 0) & 0xFFFFFFFF);
|
readonly get => (uint)((Internal.Id4 >> 0) & 0xFFFFFFFF);
|
||||||
set => Internal.Id4 = (Internal.Id4 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
set => Internal.Id4 = (Internal.Id4 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint StencilBackReference
|
public uint StencilBackReference
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id4 >> 32) & 0xFFFFFFFF);
|
readonly get => (uint)((Internal.Id4 >> 32) & 0xFFFFFFFF);
|
||||||
set => Internal.Id4 = (Internal.Id4 & 0xFFFFFFFF) | ((ulong)value << 32);
|
set => Internal.Id4 = (Internal.Id4 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float MinDepthBounds
|
public float MinDepthBounds
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id5 >> 0) & 0xFFFFFFFF));
|
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id5 >> 0) & 0xFFFFFFFF));
|
||||||
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float MaxDepthBounds
|
public float MaxDepthBounds
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id5 >> 32) & 0xFFFFFFFF));
|
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id5 >> 32) & 0xFFFFFFFF));
|
||||||
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PolygonMode PolygonMode
|
public PolygonMode PolygonMode
|
||||||
{
|
{
|
||||||
get => (PolygonMode)((Internal.Id6 >> 0) & 0x3FFFFFFF);
|
readonly get => (PolygonMode)((Internal.Id6 >> 0) & 0x3FFFFFFF);
|
||||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFFC0000000) | ((ulong)value << 0);
|
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFFC0000000) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint StagesCount
|
public uint StagesCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id6 >> 30) & 0xFF);
|
readonly get => (byte)((Internal.Id6 >> 30) & 0xFF);
|
||||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFC03FFFFFFF) | ((ulong)value << 30);
|
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFC03FFFFFFF) | ((ulong)value << 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint VertexAttributeDescriptionsCount
|
public uint VertexAttributeDescriptionsCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id6 >> 38) & 0xFF);
|
readonly get => (byte)((Internal.Id6 >> 38) & 0xFF);
|
||||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFC03FFFFFFFFF) | ((ulong)value << 38);
|
set => Internal.Id6 = (Internal.Id6 & 0xFFFFC03FFFFFFFFF) | ((ulong)value << 38);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint VertexBindingDescriptionsCount
|
public uint VertexBindingDescriptionsCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id6 >> 46) & 0xFF);
|
readonly get => (byte)((Internal.Id6 >> 46) & 0xFF);
|
||||||
set => Internal.Id6 = (Internal.Id6 & 0xFFC03FFFFFFFFFFF) | ((ulong)value << 46);
|
set => Internal.Id6 = (Internal.Id6 & 0xFFC03FFFFFFFFFFF) | ((ulong)value << 46);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint ViewportsCount
|
public uint ViewportsCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id6 >> 54) & 0xFF);
|
readonly get => (byte)((Internal.Id6 >> 54) & 0xFF);
|
||||||
set => Internal.Id6 = (Internal.Id6 & 0xC03FFFFFFFFFFFFF) | ((ulong)value << 54);
|
set => Internal.Id6 = (Internal.Id6 & 0xC03FFFFFFFFFFFFF) | ((ulong)value << 54);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint ScissorsCount
|
public uint ScissorsCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id7 >> 0) & 0xFF);
|
readonly get => (byte)((Internal.Id7 >> 0) & 0xFF);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFFFF00) | ((ulong)value << 0);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFFFF00) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint ColorBlendAttachmentStateCount
|
public uint ColorBlendAttachmentStateCount
|
||||||
{
|
{
|
||||||
get => (byte)((Internal.Id7 >> 8) & 0xFF);
|
readonly get => (byte)((Internal.Id7 >> 8) & 0xFF);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFF00FF) | ((ulong)value << 8);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFF00FF) | ((ulong)value << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrimitiveTopology Topology
|
public PrimitiveTopology Topology
|
||||||
{
|
{
|
||||||
get => (PrimitiveTopology)((Internal.Id7 >> 16) & 0xF);
|
readonly get => (PrimitiveTopology)((Internal.Id7 >> 16) & 0xF);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFF0FFFF) | ((ulong)value << 16);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFF0FFFF) | ((ulong)value << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LogicOp LogicOp
|
public LogicOp LogicOp
|
||||||
{
|
{
|
||||||
get => (LogicOp)((Internal.Id7 >> 20) & 0xF);
|
readonly get => (LogicOp)((Internal.Id7 >> 20) & 0xF);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFF0FFFFF) | ((ulong)value << 20);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFF0FFFFF) | ((ulong)value << 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompareOp DepthCompareOp
|
public CompareOp DepthCompareOp
|
||||||
{
|
{
|
||||||
get => (CompareOp)((Internal.Id7 >> 24) & 0x7);
|
readonly get => (CompareOp)((Internal.Id7 >> 24) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFF8FFFFFF) | ((ulong)value << 24);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFF8FFFFFF) | ((ulong)value << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilFrontFailOp
|
public StencilOp StencilFrontFailOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id7 >> 27) & 0x7);
|
readonly get => (StencilOp)((Internal.Id7 >> 27) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFC7FFFFFF) | ((ulong)value << 27);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFC7FFFFFF) | ((ulong)value << 27);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilFrontPassOp
|
public StencilOp StencilFrontPassOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id7 >> 30) & 0x7);
|
readonly get => (StencilOp)((Internal.Id7 >> 30) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFE3FFFFFFF) | ((ulong)value << 30);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFE3FFFFFFF) | ((ulong)value << 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilFrontDepthFailOp
|
public StencilOp StencilFrontDepthFailOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id7 >> 33) & 0x7);
|
readonly get => (StencilOp)((Internal.Id7 >> 33) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFF1FFFFFFFF) | ((ulong)value << 33);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFF1FFFFFFFF) | ((ulong)value << 33);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompareOp StencilFrontCompareOp
|
public CompareOp StencilFrontCompareOp
|
||||||
{
|
{
|
||||||
get => (CompareOp)((Internal.Id7 >> 36) & 0x7);
|
readonly get => (CompareOp)((Internal.Id7 >> 36) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFF8FFFFFFFFF) | ((ulong)value << 36);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFF8FFFFFFFFF) | ((ulong)value << 36);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilBackFailOp
|
public StencilOp StencilBackFailOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id7 >> 39) & 0x7);
|
readonly get => (StencilOp)((Internal.Id7 >> 39) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFC7FFFFFFFFF) | ((ulong)value << 39);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFC7FFFFFFFFF) | ((ulong)value << 39);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilBackPassOp
|
public StencilOp StencilBackPassOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id7 >> 42) & 0x7);
|
readonly get => (StencilOp)((Internal.Id7 >> 42) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFE3FFFFFFFFFF) | ((ulong)value << 42);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFFE3FFFFFFFFFF) | ((ulong)value << 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StencilOp StencilBackDepthFailOp
|
public StencilOp StencilBackDepthFailOp
|
||||||
{
|
{
|
||||||
get => (StencilOp)((Internal.Id7 >> 45) & 0x7);
|
readonly get => (StencilOp)((Internal.Id7 >> 45) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFF1FFFFFFFFFFF) | ((ulong)value << 45);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFFF1FFFFFFFFFFF) | ((ulong)value << 45);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompareOp StencilBackCompareOp
|
public CompareOp StencilBackCompareOp
|
||||||
{
|
{
|
||||||
get => (CompareOp)((Internal.Id7 >> 48) & 0x7);
|
readonly get => (CompareOp)((Internal.Id7 >> 48) & 0x7);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFF8FFFFFFFFFFFF) | ((ulong)value << 48);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFF8FFFFFFFFFFFF) | ((ulong)value << 48);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CullModeFlags CullMode
|
public CullModeFlags CullMode
|
||||||
{
|
{
|
||||||
get => (CullModeFlags)((Internal.Id7 >> 51) & 0x3);
|
readonly get => (CullModeFlags)((Internal.Id7 >> 51) & 0x3);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFE7FFFFFFFFFFFF) | ((ulong)value << 51);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFE7FFFFFFFFFFFF) | ((ulong)value << 51);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool PrimitiveRestartEnable
|
public bool PrimitiveRestartEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 53) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 53) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFDFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 53);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFDFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 53);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthClampEnable
|
public bool DepthClampEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 54) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 54) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFFBFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 54);
|
set => Internal.Id7 = (Internal.Id7 & 0xFFBFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 54);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RasterizerDiscardEnable
|
public bool RasterizerDiscardEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 55) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 55) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFF7FFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 55);
|
set => Internal.Id7 = (Internal.Id7 & 0xFF7FFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 55);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FrontFace FrontFace
|
public FrontFace FrontFace
|
||||||
{
|
{
|
||||||
get => (FrontFace)((Internal.Id7 >> 56) & 0x1);
|
readonly get => (FrontFace)((Internal.Id7 >> 56) & 0x1);
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFEFFFFFFFFFFFFFF) | ((ulong)value << 56);
|
set => Internal.Id7 = (Internal.Id7 & 0xFEFFFFFFFFFFFFFF) | ((ulong)value << 56);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthBiasEnable
|
public bool DepthBiasEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 57) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 57) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFDFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 57);
|
set => Internal.Id7 = (Internal.Id7 & 0xFDFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 57);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthTestEnable
|
public bool DepthTestEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 58) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 58) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xFBFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 58);
|
set => Internal.Id7 = (Internal.Id7 & 0xFBFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 58);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthWriteEnable
|
public bool DepthWriteEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 59) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 59) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xF7FFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 59);
|
set => Internal.Id7 = (Internal.Id7 & 0xF7FFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 59);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthBoundsTestEnable
|
public bool DepthBoundsTestEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 60) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 60) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xEFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 60);
|
set => Internal.Id7 = (Internal.Id7 & 0xEFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StencilTestEnable
|
public bool StencilTestEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 61) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 61) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xDFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 61);
|
set => Internal.Id7 = (Internal.Id7 & 0xDFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 61);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool LogicOpEnable
|
public bool LogicOpEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 62) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 62) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0xBFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 62);
|
set => Internal.Id7 = (Internal.Id7 & 0xBFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 62);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasDepthStencil
|
public bool HasDepthStencil
|
||||||
{
|
{
|
||||||
get => ((Internal.Id7 >> 63) & 0x1) != 0UL;
|
readonly get => ((Internal.Id7 >> 63) & 0x1) != 0UL;
|
||||||
set => Internal.Id7 = (Internal.Id7 & 0x7FFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 63);
|
set => Internal.Id7 = (Internal.Id7 & 0x7FFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 63);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint PatchControlPoints
|
public uint PatchControlPoints
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id8 >> 0) & 0xFFFFFFFF);
|
readonly get => (uint)((Internal.Id8 >> 0) & 0xFFFFFFFF);
|
||||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint SamplesCount
|
public uint SamplesCount
|
||||||
{
|
{
|
||||||
get => (uint)((Internal.Id8 >> 32) & 0xFFFFFFFF);
|
readonly get => (uint)((Internal.Id8 >> 32) & 0xFFFFFFFF);
|
||||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF) | ((ulong)value << 32);
|
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AlphaToCoverageEnable
|
public bool AlphaToCoverageEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 0) & 0x1) != 0UL;
|
readonly get => ((Internal.Id9 >> 0) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFE) | ((value ? 1UL : 0UL) << 0);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFE) | ((value ? 1UL : 0UL) << 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AlphaToOneEnable
|
public bool AlphaToOneEnable
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 1) & 0x1) != 0UL;
|
readonly get => ((Internal.Id9 >> 1) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AdvancedBlendSrcPreMultiplied
|
public bool AdvancedBlendSrcPreMultiplied
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 2) & 0x1) != 0UL;
|
readonly get => ((Internal.Id9 >> 2) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFB) | ((value ? 1UL : 0UL) << 2);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFB) | ((value ? 1UL : 0UL) << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AdvancedBlendDstPreMultiplied
|
public bool AdvancedBlendDstPreMultiplied
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 3) & 0x1) != 0UL;
|
readonly get => ((Internal.Id9 >> 3) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFF7) | ((value ? 1UL : 0UL) << 3);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFF7) | ((value ? 1UL : 0UL) << 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlendOverlapEXT AdvancedBlendOverlap
|
public BlendOverlapEXT AdvancedBlendOverlap
|
||||||
{
|
{
|
||||||
get => (BlendOverlapEXT)((Internal.Id9 >> 4) & 0x3);
|
readonly get => (BlendOverlapEXT)((Internal.Id9 >> 4) & 0x3);
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFCF) | ((ulong)value << 4);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFCF) | ((ulong)value << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DepthMode
|
public bool DepthMode
|
||||||
{
|
{
|
||||||
get => ((Internal.Id9 >> 6) & 0x1) != 0UL;
|
readonly get => ((Internal.Id9 >> 6) & 0x1) != 0UL;
|
||||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFBF) | ((value ? 1UL : 0UL) << 6);
|
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFBF) | ((value ? 1UL : 0UL) << 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,10 +325,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
for (int index = 0; index < Constants.MaxShaderStages; index++)
|
for (int index = 0; index < Constants.MaxShaderStages; index++)
|
||||||
{
|
{
|
||||||
StageRequiredSubgroupSizes[index] = new PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT()
|
StageRequiredSubgroupSizes[index] = new PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineShaderStageRequiredSubgroupSizeCreateInfoExt,
|
SType = StructureType.PipelineShaderStageRequiredSubgroupSizeCreateInfoExt,
|
||||||
RequiredSubgroupSize = RequiredSubgroupSize
|
RequiredSubgroupSize = RequiredSubgroupSize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,12 +357,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
UpdateStageRequiredSubgroupSizes(gd, 1);
|
UpdateStageRequiredSubgroupSizes(gd, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineCreateInfo = new ComputePipelineCreateInfo()
|
var pipelineCreateInfo = new ComputePipelineCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ComputePipelineCreateInfo,
|
SType = StructureType.ComputePipelineCreateInfo,
|
||||||
Stage = Stages[0],
|
Stage = Stages[0],
|
||||||
BasePipelineIndex = -1,
|
BasePipelineIndex = -1,
|
||||||
Layout = PipelineLayout
|
Layout = PipelineLayout,
|
||||||
};
|
};
|
||||||
|
|
||||||
Pipeline pipelineHandle = default;
|
Pipeline pipelineHandle = default;
|
||||||
|
@ -431,7 +431,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
VertexAttributeDescriptionCount = VertexAttributeDescriptionsCount,
|
VertexAttributeDescriptionCount = VertexAttributeDescriptionsCount,
|
||||||
PVertexAttributeDescriptions = isMoltenVk ? pVertexAttributeDescriptions2 : pVertexAttributeDescriptions,
|
PVertexAttributeDescriptions = isMoltenVk ? pVertexAttributeDescriptions2 : pVertexAttributeDescriptions,
|
||||||
VertexBindingDescriptionCount = VertexBindingDescriptionsCount,
|
VertexBindingDescriptionCount = VertexBindingDescriptionsCount,
|
||||||
PVertexBindingDescriptions = pVertexBindingDescriptions
|
PVertexBindingDescriptions = pVertexBindingDescriptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool primitiveRestartEnable = PrimitiveRestartEnable;
|
bool primitiveRestartEnable = PrimitiveRestartEnable;
|
||||||
|
@ -453,20 +453,20 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
primitiveRestartEnable &= topologySupportsRestart;
|
primitiveRestartEnable &= topologySupportsRestart;
|
||||||
|
|
||||||
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo()
|
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
SType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
||||||
PrimitiveRestartEnable = primitiveRestartEnable,
|
PrimitiveRestartEnable = primitiveRestartEnable,
|
||||||
Topology = Topology
|
Topology = Topology,
|
||||||
};
|
};
|
||||||
|
|
||||||
var tessellationState = new PipelineTessellationStateCreateInfo()
|
var tessellationState = new PipelineTessellationStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineTessellationStateCreateInfo,
|
SType = StructureType.PipelineTessellationStateCreateInfo,
|
||||||
PatchControlPoints = PatchControlPoints
|
PatchControlPoints = PatchControlPoints,
|
||||||
};
|
};
|
||||||
|
|
||||||
var rasterizationState = new PipelineRasterizationStateCreateInfo()
|
var rasterizationState = new PipelineRasterizationStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineRasterizationStateCreateInfo,
|
SType = StructureType.PipelineRasterizationStateCreateInfo,
|
||||||
DepthClampEnable = DepthClampEnable,
|
DepthClampEnable = DepthClampEnable,
|
||||||
|
@ -478,24 +478,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DepthBiasEnable = DepthBiasEnable,
|
DepthBiasEnable = DepthBiasEnable,
|
||||||
DepthBiasClamp = DepthBiasClamp,
|
DepthBiasClamp = DepthBiasClamp,
|
||||||
DepthBiasConstantFactor = DepthBiasConstantFactor,
|
DepthBiasConstantFactor = DepthBiasConstantFactor,
|
||||||
DepthBiasSlopeFactor = DepthBiasSlopeFactor
|
DepthBiasSlopeFactor = DepthBiasSlopeFactor,
|
||||||
};
|
};
|
||||||
|
|
||||||
var viewportState = new PipelineViewportStateCreateInfo()
|
var viewportState = new PipelineViewportStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineViewportStateCreateInfo,
|
SType = StructureType.PipelineViewportStateCreateInfo,
|
||||||
ViewportCount = ViewportsCount,
|
ViewportCount = ViewportsCount,
|
||||||
PViewports = pViewports,
|
PViewports = pViewports,
|
||||||
ScissorCount = ScissorsCount,
|
ScissorCount = ScissorsCount,
|
||||||
PScissors = pScissors
|
PScissors = pScissors,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsDepthClipControl)
|
if (gd.Capabilities.SupportsDepthClipControl)
|
||||||
{
|
{
|
||||||
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT()
|
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt,
|
SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt,
|
||||||
NegativeOneToOne = DepthMode
|
NegativeOneToOne = DepthMode,
|
||||||
};
|
};
|
||||||
|
|
||||||
viewportState.PNext = &viewportDepthClipControlState;
|
viewportState.PNext = &viewportDepthClipControlState;
|
||||||
|
@ -508,7 +508,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
RasterizationSamples = TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, SamplesCount),
|
RasterizationSamples = TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, SamplesCount),
|
||||||
MinSampleShading = 1,
|
MinSampleShading = 1,
|
||||||
AlphaToCoverageEnable = AlphaToCoverageEnable,
|
AlphaToCoverageEnable = AlphaToCoverageEnable,
|
||||||
AlphaToOneEnable = AlphaToOneEnable
|
AlphaToOneEnable = AlphaToOneEnable,
|
||||||
};
|
};
|
||||||
|
|
||||||
var stencilFront = new StencilOpState(
|
var stencilFront = new StencilOpState(
|
||||||
|
@ -529,7 +529,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
StencilBackWriteMask,
|
StencilBackWriteMask,
|
||||||
StencilBackReference);
|
StencilBackReference);
|
||||||
|
|
||||||
var depthStencilState = new PipelineDepthStencilStateCreateInfo()
|
var depthStencilState = new PipelineDepthStencilStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineDepthStencilStateCreateInfo,
|
SType = StructureType.PipelineDepthStencilStateCreateInfo,
|
||||||
DepthTestEnable = DepthTestEnable,
|
DepthTestEnable = DepthTestEnable,
|
||||||
|
@ -540,7 +540,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Front = stencilFront,
|
Front = stencilFront,
|
||||||
Back = stencilBack,
|
Back = stencilBack,
|
||||||
MinDepthBounds = MinDepthBounds,
|
MinDepthBounds = MinDepthBounds,
|
||||||
MaxDepthBounds = MaxDepthBounds
|
MaxDepthBounds = MaxDepthBounds,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint blendEnables = 0;
|
uint blendEnables = 0;
|
||||||
|
@ -564,13 +564,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var colorBlendState = new PipelineColorBlendStateCreateInfo()
|
var colorBlendState = new PipelineColorBlendStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
||||||
LogicOpEnable = LogicOpEnable,
|
LogicOpEnable = LogicOpEnable,
|
||||||
LogicOp = LogicOp,
|
LogicOp = LogicOp,
|
||||||
AttachmentCount = ColorBlendAttachmentStateCount,
|
AttachmentCount = ColorBlendAttachmentStateCount,
|
||||||
PAttachments = pColorBlendAttachmentState
|
PAttachments = pColorBlendAttachmentState,
|
||||||
};
|
};
|
||||||
|
|
||||||
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
||||||
|
@ -579,12 +579,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
!AdvancedBlendDstPreMultiplied ||
|
!AdvancedBlendDstPreMultiplied ||
|
||||||
AdvancedBlendOverlap != BlendOverlapEXT.UncorrelatedExt)
|
AdvancedBlendOverlap != BlendOverlapEXT.UncorrelatedExt)
|
||||||
{
|
{
|
||||||
colorBlendAdvancedState = new PipelineColorBlendAdvancedStateCreateInfoEXT()
|
colorBlendAdvancedState = new PipelineColorBlendAdvancedStateCreateInfoEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineColorBlendAdvancedStateCreateInfoExt,
|
SType = StructureType.PipelineColorBlendAdvancedStateCreateInfoExt,
|
||||||
SrcPremultiplied = AdvancedBlendSrcPreMultiplied,
|
SrcPremultiplied = AdvancedBlendSrcPreMultiplied,
|
||||||
DstPremultiplied = AdvancedBlendDstPreMultiplied,
|
DstPremultiplied = AdvancedBlendDstPreMultiplied,
|
||||||
BlendOverlap = AdvancedBlendOverlap
|
BlendOverlap = AdvancedBlendOverlap,
|
||||||
};
|
};
|
||||||
|
|
||||||
colorBlendState.PNext = &colorBlendAdvancedState;
|
colorBlendState.PNext = &colorBlendAdvancedState;
|
||||||
|
@ -609,11 +609,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
dynamicStates[8] = DynamicState.VertexInputBindingStrideExt;
|
dynamicStates[8] = DynamicState.VertexInputBindingStrideExt;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo()
|
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineDynamicStateCreateInfo,
|
SType = StructureType.PipelineDynamicStateCreateInfo,
|
||||||
DynamicStateCount = (uint)dynamicStatesCount,
|
DynamicStateCount = (uint)dynamicStatesCount,
|
||||||
PDynamicStates = dynamicStates
|
PDynamicStates = dynamicStates,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (gd.Capabilities.SupportsSubgroupSizeControl)
|
if (gd.Capabilities.SupportsSubgroupSizeControl)
|
||||||
|
@ -621,7 +621,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
UpdateStageRequiredSubgroupSizes(gd, (int)StagesCount);
|
UpdateStageRequiredSubgroupSizes(gd, (int)StagesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
var pipelineCreateInfo = new GraphicsPipelineCreateInfo()
|
var pipelineCreateInfo = new GraphicsPipelineCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.GraphicsPipelineCreateInfo,
|
SType = StructureType.GraphicsPipelineCreateInfo,
|
||||||
StageCount = StagesCount,
|
StageCount = StagesCount,
|
||||||
|
@ -637,7 +637,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PDynamicState = &pipelineDynamicStateCreateInfo,
|
PDynamicState = &pipelineDynamicStateCreateInfo,
|
||||||
Layout = PipelineLayout,
|
Layout = PipelineLayout,
|
||||||
RenderPass = renderPass,
|
RenderPass = renderPass,
|
||||||
BasePipelineIndex = -1
|
BasePipelineIndex = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateGraphicsPipelines(device, cache, 1, &pipelineCreateInfo, null, &pipelineHandle).ThrowOnError();
|
gd.Api.CreateGraphicsPipelines(device, cache, 1, &pipelineCreateInfo, null, &pipelineHandle).ThrowOnError();
|
||||||
|
@ -659,7 +659,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void UpdateStageRequiredSubgroupSizes(VulkanRenderer gd, int count)
|
private readonly unsafe void UpdateStageRequiredSubgroupSizes(VulkanRenderer gd, int count)
|
||||||
{
|
{
|
||||||
for (int index = 0; index < count; index++)
|
for (int index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
|
@ -728,7 +728,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
Stages.Dispose();
|
Stages.Dispose();
|
||||||
StageRequiredSubgroupSizes.Dispose();
|
StageRequiredSubgroupSizes.Dispose();
|
||||||
|
|
|
@ -22,12 +22,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public ulong Id8;
|
public ulong Id8;
|
||||||
public ulong Id9;
|
public ulong Id9;
|
||||||
|
|
||||||
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
private readonly uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||||
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
private readonly uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||||
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
|
private readonly uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||||
private uint ScissorsCount => (byte)(Id7 & 0xFF);
|
private readonly bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||||
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
|
||||||
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
|
||||||
|
|
||||||
public Array32<VertexInputAttributeDescription> VertexAttributeDescriptions;
|
public Array32<VertexInputAttributeDescription> VertexAttributeDescriptions;
|
||||||
public Array33<VertexInputBindingDescription> VertexBindingDescriptions;
|
public Array33<VertexInputBindingDescription> VertexBindingDescriptions;
|
||||||
|
@ -37,7 +35,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public Array9<Format> AttachmentFormats;
|
public Array9<Format> AttachmentFormats;
|
||||||
public uint AttachmentIntegerFormatMask;
|
public uint AttachmentIntegerFormatMask;
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public readonly override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
return obj is PipelineUid other && Equals(other);
|
return obj is PipelineUid other && Equals(other);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +74,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private static bool SequenceEqual<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, uint count) where T : unmanaged
|
private static bool SequenceEqual<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, uint count) where T : unmanaged
|
||||||
{
|
{
|
||||||
return MemoryMarshal.Cast<T, byte>(x.Slice(0, (int)count)).SequenceEqual(MemoryMarshal.Cast<T, byte>(y.Slice(0, (int)count)));
|
return MemoryMarshal.Cast<T, byte>(x[..(int)count]).SequenceEqual(MemoryMarshal.Cast<T, byte>(y[..(int)count]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
|
|
|
@ -23,10 +23,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
private readonly BufferHolder _buffer;
|
private readonly BufferHolder _buffer;
|
||||||
private readonly IntPtr _bufferMap;
|
private readonly IntPtr _bufferMap;
|
||||||
private readonly CounterType _type;
|
private readonly CounterType _type;
|
||||||
private bool _result32Bit;
|
private readonly bool _result32Bit;
|
||||||
private bool _isSupported;
|
private readonly bool _isSupported;
|
||||||
|
|
||||||
private long _defaultValue;
|
private readonly long _defaultValue;
|
||||||
private int? _resetSequence;
|
private int? _resetSequence;
|
||||||
|
|
||||||
public unsafe BufferedQuery(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type, bool result32Bit)
|
public unsafe BufferedQuery(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type, bool result32Bit)
|
||||||
|
@ -44,12 +44,12 @@ 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()
|
var queryPoolCreateInfo = new QueryPoolCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.QueryPoolCreateInfo,
|
SType = StructureType.QueryPoolCreateInfo,
|
||||||
QueryCount = 1,
|
QueryCount = 1,
|
||||||
QueryType = GetQueryType(type),
|
QueryType = GetQueryType(type),
|
||||||
PipelineStatistics = flags
|
PipelineStatistics = flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateQueryPool(device, queryPoolCreateInfo, null, out _queryPool).ThrowOnError();
|
gd.Api.CreateQueryPool(device, queryPoolCreateInfo, null, out _queryPool).ThrowOnError();
|
||||||
|
@ -63,14 +63,14 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool QueryTypeSupported(VulkanRenderer gd, CounterType type)
|
private static bool QueryTypeSupported(VulkanRenderer gd, CounterType type)
|
||||||
{
|
{
|
||||||
return type switch
|
return type switch
|
||||||
{
|
{
|
||||||
CounterType.SamplesPassed => true,
|
CounterType.SamplesPassed => true,
|
||||||
CounterType.PrimitivesGenerated => gd.Capabilities.SupportsPipelineStatisticsQuery,
|
CounterType.PrimitivesGenerated => gd.Capabilities.SupportsPipelineStatisticsQuery,
|
||||||
CounterType.TransformFeedbackPrimitivesWritten => gd.Capabilities.SupportsTransformFeedbackQueries,
|
CounterType.TransformFeedbackPrimitivesWritten => gd.Capabilities.SupportsTransformFeedbackQueries,
|
||||||
_ => false
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
CounterType.SamplesPassed => QueryType.Occlusion,
|
CounterType.SamplesPassed => QueryType.Occlusion,
|
||||||
CounterType.PrimitivesGenerated => QueryType.PipelineStatistics,
|
CounterType.PrimitivesGenerated => QueryType.PipelineStatistics,
|
||||||
CounterType.TransformFeedbackPrimitivesWritten => QueryType.TransformFeedbackStreamExt,
|
CounterType.TransformFeedbackPrimitivesWritten => QueryType.TransformFeedbackStreamExt,
|
||||||
_ => QueryType.Occlusion
|
_ => QueryType.Occlusion,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
_resetSequence = null;
|
_resetSequence = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void End(bool withResult)
|
public void End(bool withResult)
|
||||||
{
|
{
|
||||||
if (_isSupported)
|
if (_isSupported)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
public CounterType Type { get; }
|
public CounterType Type { get; }
|
||||||
public bool Disposed { get; private set; }
|
public bool Disposed { get; private set; }
|
||||||
|
|
||||||
private Queue<CounterQueueEvent> _events = new Queue<CounterQueueEvent>();
|
private readonly Queue<CounterQueueEvent> _events = new();
|
||||||
private CounterQueueEvent _current;
|
private CounterQueueEvent _current;
|
||||||
|
|
||||||
private ulong _accumulatedCounter;
|
private ulong _accumulatedCounter;
|
||||||
|
@ -26,12 +26,12 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
|
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new();
|
||||||
|
|
||||||
private Queue<BufferedQuery> _queryPool;
|
private readonly Queue<BufferedQuery> _queryPool;
|
||||||
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
private readonly AutoResetEvent _queuedEvent = new(false);
|
||||||
private AutoResetEvent _wakeSignal = new AutoResetEvent(false);
|
private readonly AutoResetEvent _wakeSignal = new(false);
|
||||||
private AutoResetEvent _eventConsumed = new AutoResetEvent(false);
|
private readonly AutoResetEvent _eventConsumed = new(false);
|
||||||
|
|
||||||
private Thread _consumerThread;
|
private readonly Thread _consumerThread;
|
||||||
|
|
||||||
public int ResetSequence { get; private set; }
|
public int ResetSequence { get; private set; }
|
||||||
|
|
||||||
|
@ -116,12 +116,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
BufferedQuery result = _queryPool.Dequeue();
|
BufferedQuery result = _queryPool.Dequeue();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return new BufferedQuery(_gd, _device, _pipeline, Type, _gd.IsAmdWindows);
|
return new BufferedQuery(_gd, _device, _pipeline, Type, _gd.IsAmdWindows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
internal void ReturnQueryObject(BufferedQuery query)
|
internal void ReturnQueryObject(BufferedQuery query)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,10 +16,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||||
|
|
||||||
public ulong DrawIndex { get; }
|
public ulong DrawIndex { get; }
|
||||||
|
|
||||||
private CounterQueue _queue;
|
private readonly CounterQueue _queue;
|
||||||
private BufferedQuery _counter;
|
private readonly BufferedQuery _counter;
|
||||||
|
|
||||||
private bool _hostAccessReserved = false;
|
private bool _hostAccessReserved;
|
||||||
private int _refCount = 1; // Starts with a reference from the counter queue.
|
private int _refCount = 1; // Starts with a reference from the counter queue.
|
||||||
|
|
||||||
private readonly object _lock = new();
|
private readonly object _lock = new();
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ResourceType.StorageBuffer => PipelineBase.StorageSetIndex,
|
ResourceType.StorageBuffer => PipelineBase.StorageSetIndex,
|
||||||
ResourceType.TextureAndSampler or ResourceType.BufferTexture => PipelineBase.TextureSetIndex,
|
ResourceType.TextureAndSampler or ResourceType.BufferTexture => PipelineBase.TextureSetIndex,
|
||||||
ResourceType.Image or ResourceType.BufferImage => PipelineBase.ImageSetIndex,
|
ResourceType.Image or ResourceType.BufferImage => PipelineBase.ImageSetIndex,
|
||||||
_ => throw new ArgumentException($"Invalid resource type \"{type}\".")
|
_ => throw new ArgumentException($"Invalid resource type \"{type}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
ResourceAccess access = IsReadOnlyType(type) ? ResourceAccess.Read : ResourceAccess.ReadWrite;
|
ResourceAccess access = IsReadOnlyType(type) ? ResourceAccess.Read : ResourceAccess.ReadWrite;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
|
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -8,13 +9,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
private readonly Auto<DisposableSampler> _sampler;
|
private readonly Auto<DisposableSampler> _sampler;
|
||||||
|
|
||||||
public unsafe SamplerHolder(VulkanRenderer gd, Device device, GAL.SamplerCreateInfo info)
|
public unsafe SamplerHolder(VulkanRenderer gd, Device device, SamplerCreateInfo info)
|
||||||
{
|
{
|
||||||
_gd = gd;
|
_gd = gd;
|
||||||
|
|
||||||
gd.Samplers.Add(this);
|
gd.Samplers.Add(this);
|
||||||
|
|
||||||
(Filter minFilter, SamplerMipmapMode mipFilter) = EnumConversion.Convert(info.MinFilter);
|
(Filter minFilter, SamplerMipmapMode mipFilter) = info.MinFilter.Convert();
|
||||||
|
|
||||||
float minLod = info.MinLod;
|
float minLod = info.MinLod;
|
||||||
float maxLod = info.MaxLod;
|
float maxLod = info.MaxLod;
|
||||||
|
@ -27,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var borderColor = GetConstrainedBorderColor(info.BorderColor, out var cantConstrain);
|
var borderColor = GetConstrainedBorderColor(info.BorderColor, out var cantConstrain);
|
||||||
|
|
||||||
var samplerCreateInfo = new Silk.NET.Vulkan.SamplerCreateInfo()
|
var samplerCreateInfo = new Silk.NET.Vulkan.SamplerCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.SamplerCreateInfo,
|
SType = StructureType.SamplerCreateInfo,
|
||||||
MagFilter = info.MagFilter.Convert(),
|
MagFilter = info.MagFilter.Convert(),
|
||||||
|
@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
MinLod = minLod,
|
MinLod = minLod,
|
||||||
MaxLod = maxLod,
|
MaxLod = maxLod,
|
||||||
BorderColor = borderColor,
|
BorderColor = borderColor,
|
||||||
UnnormalizedCoordinates = false // TODO: Use unnormalized coordinates.
|
UnnormalizedCoordinates = false, // TODO: Use unnormalized coordinates.
|
||||||
};
|
};
|
||||||
|
|
||||||
SamplerCustomBorderColorCreateInfoEXT customBorderColor;
|
SamplerCustomBorderColorCreateInfoEXT customBorderColor;
|
||||||
|
@ -57,10 +58,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
info.BorderColor.Blue,
|
info.BorderColor.Blue,
|
||||||
info.BorderColor.Alpha);
|
info.BorderColor.Alpha);
|
||||||
|
|
||||||
customBorderColor = new SamplerCustomBorderColorCreateInfoEXT()
|
customBorderColor = new SamplerCustomBorderColorCreateInfoEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.SamplerCustomBorderColorCreateInfoExt,
|
SType = StructureType.SamplerCustomBorderColorCreateInfoExt,
|
||||||
CustomBorderColor = color
|
CustomBorderColor = color,
|
||||||
};
|
};
|
||||||
|
|
||||||
samplerCreateInfo.PNext = &customBorderColor;
|
samplerCreateInfo.PNext = &customBorderColor;
|
||||||
|
@ -86,7 +87,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
cantConstrain = false;
|
cantConstrain = false;
|
||||||
return BorderColor.FloatOpaqueBlack;
|
return BorderColor.FloatOpaqueBlack;
|
||||||
}
|
}
|
||||||
else if (a == 0f)
|
|
||||||
|
if (a == 0f)
|
||||||
{
|
{
|
||||||
cantConstrain = false;
|
cantConstrain = false;
|
||||||
return BorderColor.FloatTransparentBlack;
|
return BorderColor.FloatTransparentBlack;
|
||||||
|
|
|
@ -11,16 +11,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
private VkSemaphore _semaphore;
|
private VkSemaphore _semaphore;
|
||||||
private int _referenceCount;
|
private int _referenceCount;
|
||||||
public bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
public unsafe SemaphoreHolder(Vk api, Device device)
|
public unsafe SemaphoreHolder(Vk api, Device device)
|
||||||
{
|
{
|
||||||
_api = api;
|
_api = api;
|
||||||
_device = device;
|
_device = device;
|
||||||
|
|
||||||
var semaphoreCreateInfo = new SemaphoreCreateInfo()
|
var semaphoreCreateInfo = new SemaphoreCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.SemaphoreCreateInfo
|
SType = StructureType.SemaphoreCreateInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CreateSemaphore(device, in semaphoreCreateInfo, null, out _semaphore).ThrowOnError();
|
api.CreateSemaphore(device, in semaphoreCreateInfo, null, out _semaphore).ThrowOnError();
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
// The shaderc.net dependency's Options constructor and dispose are not thread safe.
|
// The shaderc.net dependency's Options constructor and dispose are not thread safe.
|
||||||
// Take this lock when using them.
|
// Take this lock when using them.
|
||||||
private static object _shaderOptionsLock = new object();
|
private static readonly object _shaderOptionsLock = new();
|
||||||
|
|
||||||
private static readonly IntPtr _ptrMainEntryPointName = Marshal.StringToHGlobalAnsi("main");
|
private static readonly IntPtr _ptrMainEntryPointName = Marshal.StringToHGlobalAnsi("main");
|
||||||
|
|
||||||
|
@ -57,11 +57,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
fixed (byte* pCode = spirv)
|
fixed (byte* pCode = spirv)
|
||||||
{
|
{
|
||||||
var shaderModuleCreateInfo = new ShaderModuleCreateInfo()
|
var shaderModuleCreateInfo = new ShaderModuleCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ShaderModuleCreateInfo,
|
SType = StructureType.ShaderModuleCreateInfo,
|
||||||
CodeSize = (uint)spirv.Length,
|
CodeSize = (uint)spirv.Length,
|
||||||
PCode = (uint*)pCode
|
PCode = (uint*)pCode,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CreateShaderModule(device, shaderModuleCreateInfo, null, out _module).ThrowOnError();
|
api.CreateShaderModule(device, shaderModuleCreateInfo, null, out _module).ThrowOnError();
|
||||||
|
@ -80,12 +80,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
options = new Options(false)
|
options = new Options(false)
|
||||||
{
|
{
|
||||||
SourceLanguage = SourceLanguage.Glsl,
|
SourceLanguage = SourceLanguage.Glsl,
|
||||||
TargetSpirVVersion = new SpirVVersion(1, 5)
|
TargetSpirVVersion = new SpirVVersion(1, 5),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
options.SetTargetEnvironment(TargetEnvironment.Vulkan, EnvironmentVersion.Vulkan_1_2);
|
options.SetTargetEnvironment(TargetEnvironment.Vulkan, EnvironmentVersion.Vulkan_1_2);
|
||||||
Compiler compiler = new Compiler(options);
|
Compiler compiler = new(options);
|
||||||
var scr = compiler.Compile(glsl, "Ryu", GetShaderCShaderStage(stage));
|
var scr = compiler.Compile(glsl, "Ryu", GetShaderCShaderStage(stage));
|
||||||
|
|
||||||
lock (_shaderOptionsLock)
|
lock (_shaderOptionsLock)
|
||||||
|
@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
byte[] code = new byte[(scr.CodeLength + 3) & ~3];
|
byte[] code = new byte[(scr.CodeLength + 3) & ~3];
|
||||||
|
|
||||||
spirvBytes.CopyTo(code.AsSpan().Slice(0, (int)scr.CodeLength));
|
spirvBytes.CopyTo(code.AsSpan()[..(int)scr.CodeLength]);
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -134,12 +134,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public unsafe PipelineShaderStageCreateInfo GetInfo()
|
public unsafe PipelineShaderStageCreateInfo GetInfo()
|
||||||
{
|
{
|
||||||
return new PipelineShaderStageCreateInfo()
|
return new PipelineShaderStageCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.PipelineShaderStageCreateInfo,
|
SType = StructureType.PipelineShaderStageCreateInfo,
|
||||||
Stage = _stage,
|
Stage = _stage,
|
||||||
Module = _module,
|
Module = _module,
|
||||||
PName = (byte*)_ptrMainEntryPointName
|
PName = (byte*)_ptrMainEntryPointName,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,13 +47,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private HashTableSlim<PipelineUid, Auto<DisposablePipeline>> _graphicsPipelineCache;
|
private HashTableSlim<PipelineUid, Auto<DisposablePipeline>> _graphicsPipelineCache;
|
||||||
private HashTableSlim<SpecData, Auto<DisposablePipeline>> _computePipelineCache;
|
private HashTableSlim<SpecData, Auto<DisposablePipeline>> _computePipelineCache;
|
||||||
|
|
||||||
private VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
private Device _device;
|
private Device _device;
|
||||||
private bool _initialized;
|
private bool _initialized;
|
||||||
|
|
||||||
private ProgramPipelineState _state;
|
private ProgramPipelineState _state;
|
||||||
private DisposableRenderPass _dummyRenderPass;
|
private DisposableRenderPass _dummyRenderPass;
|
||||||
private Task _compileTask;
|
private readonly Task _compileTask;
|
||||||
private bool _firstBackgroundUse;
|
private bool _firstBackgroundUse;
|
||||||
|
|
||||||
public ShaderCollection(
|
public ShaderCollection(
|
||||||
|
@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ShaderStageFlags.GeometryBit => 2,
|
ShaderStageFlags.GeometryBit => 2,
|
||||||
ShaderStageFlags.TessellationControlBit => 3,
|
ShaderStageFlags.TessellationControlBit => 3,
|
||||||
ShaderStageFlags.TessellationEvaluationBit => 4,
|
ShaderStageFlags.TessellationEvaluationBit => 4,
|
||||||
_ => 0
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (shader.StageFlags == ShaderStageFlags.ComputeBit)
|
if (shader.StageFlags == ShaderStageFlags.ComputeBit)
|
||||||
|
@ -143,7 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
for (int setIndex = 0; setIndex < sets.Count; setIndex++)
|
for (int setIndex = 0; setIndex < sets.Count; setIndex++)
|
||||||
{
|
{
|
||||||
List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
|
List<ResourceBindingSegment> currentSegments = new();
|
||||||
|
|
||||||
ResourceDescriptor currentDescriptor = default;
|
ResourceDescriptor currentDescriptor = default;
|
||||||
int currentCount = 0;
|
int currentCount = 0;
|
||||||
|
@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
for (int setIndex = 0; setIndex < setUsages.Count; setIndex++)
|
for (int setIndex = 0; setIndex < setUsages.Count; setIndex++)
|
||||||
{
|
{
|
||||||
List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
|
List<ResourceBindingSegment> currentSegments = new();
|
||||||
|
|
||||||
ResourceUsage currentUsage = default;
|
ResourceUsage currentUsage = default;
|
||||||
int currentCount = 0;
|
int currentCount = 0;
|
||||||
|
@ -319,7 +319,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return _infos;
|
return _infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected unsafe DisposableRenderPass CreateDummyRenderPass()
|
protected DisposableRenderPass CreateDummyRenderPass()
|
||||||
{
|
{
|
||||||
if (_dummyRenderPass.Value.Handle != 0)
|
if (_dummyRenderPass.Value.Handle != 0)
|
||||||
{
|
{
|
||||||
|
@ -331,7 +331,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void CreateBackgroundComputePipeline()
|
public void CreateBackgroundComputePipeline()
|
||||||
{
|
{
|
||||||
PipelineState pipeline = new PipelineState();
|
PipelineState pipeline = new();
|
||||||
pipeline.Initialize();
|
pipeline.Initialize();
|
||||||
|
|
||||||
pipeline.Stages[0] = _shaders[0].GetInfo();
|
pipeline.Stages[0] = _shaders[0].GetInfo();
|
||||||
|
@ -484,7 +484,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return _plce.GetNewDescriptorSetCollection(gd, commandBufferIndex, setIndex, out isNew);
|
return _plce.GetNewDescriptorSetCollection(gd, commandBufferIndex, setIndex, out isNew);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual unsafe void Dispose(bool disposing)
|
protected virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,8 +2,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
{
|
{
|
||||||
static class ShaderBinaries
|
static class ShaderBinaries
|
||||||
{
|
{
|
||||||
public static readonly byte[] ChangeBufferStrideShaderSource = new byte[]
|
public static readonly byte[] ChangeBufferStrideShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0x00, 0x8E, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0x00, 0x8E, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x60, 0x11, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
0x60, 0x11, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||||
|
@ -242,11 +241,10 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x06, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
0x06, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
||||||
0x3E, 0x00, 0x03, 0x00, 0x56, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
0x3E, 0x00, 0x03, 0x00, 0x56, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
0x57, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x59, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00,
|
0x57, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x59, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00,
|
||||||
0x38, 0x00, 0x01, 0x00
|
0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorBlitClearAlphaFragmentShaderSource = new byte[]
|
public static readonly byte[] ColorBlitClearAlphaFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x1B, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x1B, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -290,8 +288,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x09, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x09, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorBlitFragmentShaderSource = new byte[]
|
public static readonly byte[] ColorBlitFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -329,8 +326,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorBlitMsFragmentShaderSource = new byte[]
|
public static readonly byte[] ColorBlitMsFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
|
@ -384,8 +380,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorBlitVertexShaderSource = new byte[]
|
public static readonly byte[] ColorBlitVertexShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -486,8 +481,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x3C, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x3C, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorClearFFragmentShaderSource = new byte[]
|
public static readonly byte[] ColorClearFFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -514,8 +508,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x0C, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x0C, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorClearSIFragmentShaderSource = new byte[]
|
public static readonly byte[] ColorClearSIFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -545,8 +538,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x0F, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x0F, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorClearUIFragmentShaderSource = new byte[]
|
public static readonly byte[] ColorClearUIFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -576,8 +568,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x0F, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x0F, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorClearVertexShaderSource = new byte[]
|
public static readonly byte[] ColorClearVertexShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x36, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x36, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -669,8 +660,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x35, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x35, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorCopyShorteningComputeShaderSource = new byte[]
|
public static readonly byte[] ColorCopyShorteningComputeShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x79, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x79, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
|
@ -801,8 +791,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorCopyToNonMsComputeShaderSource = new byte[]
|
public static readonly byte[] ColorCopyToNonMsComputeShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x86, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x86, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
|
@ -933,8 +922,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x84, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x84, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorCopyWideningComputeShaderSource = new byte[]
|
public static readonly byte[] ColorCopyWideningComputeShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x72, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x72, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
|
@ -1060,8 +1048,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0xF8, 0x00, 0x02, 0x00, 0x70, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xF8, 0x00, 0x02, 0x00, 0x70, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorDrawToMsVertexShaderSource = new byte[]
|
public static readonly byte[] ColorDrawToMsVertexShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x2E, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x2E, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -1133,8 +1120,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x2D, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x2D, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ColorDrawToMsFragmentShaderSource = new byte[]
|
public static readonly byte[] ColorDrawToMsFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x23, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
0x23, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||||
|
@ -1236,8 +1222,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x38, 0x00, 0x01, 0x00,
|
0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ConvertD32S8ToD24S8ShaderSource = new byte[]
|
public static readonly byte[] ConvertD32S8ToD24S8ShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0x00, 0x77, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0x00, 0x77, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -1441,10 +1426,9 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x3E, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
0x3E, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||||
0x41, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00,
|
0x41, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00,
|
||||||
0x38, 0x00, 0x01, 0x00
|
0x38, 0x00, 0x01, 0x00
|
||||||
};
|
, };
|
||||||
|
|
||||||
public static readonly byte[] ConvertIndexBufferShaderSource = new byte[]
|
public static readonly byte[] ConvertIndexBufferShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x91, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x91, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x61, 0x11, 0x00, 0x00, 0x0A, 0x00, 0x07, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x4B, 0x48, 0x52, 0x5F,
|
0x61, 0x11, 0x00, 0x00, 0x0A, 0x00, 0x07, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x4B, 0x48, 0x52, 0x5F,
|
||||||
|
@ -1638,8 +1622,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x38, 0x00, 0x01, 0x00,
|
0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] ConvertIndirectDataShaderSource = new byte[]
|
public static readonly byte[] ConvertIndirectDataShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x3D, 0x01, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x3D, 0x01, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -1981,8 +1964,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0xF8, 0x00, 0x02, 0x00, 0xE5, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xF8, 0x00, 0x02, 0x00, 0xE5, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] DepthBlitFragmentShaderSource = new byte[]
|
public static readonly byte[] DepthBlitFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x17, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -2023,8 +2005,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] DepthBlitMsFragmentShaderSource = new byte[]
|
public static readonly byte[] DepthBlitMsFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
|
@ -2081,8 +2062,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] DepthDrawToMsFragmentShaderSource = new byte[]
|
public static readonly byte[] DepthDrawToMsFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x23, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
0x23, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||||
|
@ -2185,8 +2165,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x5D, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x5D, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] DepthDrawToNonMsFragmentShaderSource = new byte[]
|
public static readonly byte[] DepthDrawToNonMsFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x6A, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x6A, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||||
|
@ -2288,8 +2267,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] StencilBlitFragmentShaderSource = new byte[]
|
public static readonly byte[] StencilBlitFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x45, 0x58, 0x54, 0x5F,
|
0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x45, 0x58, 0x54, 0x5F,
|
||||||
|
@ -2336,8 +2314,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] StencilBlitMsFragmentShaderSource = new byte[]
|
public static readonly byte[] StencilBlitMsFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
|
@ -2399,8 +2376,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x08, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
0x08, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] StencilDrawToMsFragmentShaderSource = new byte[]
|
public static readonly byte[] StencilDrawToMsFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00,
|
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00,
|
||||||
|
@ -2509,8 +2485,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||||
0x38, 0x00, 0x01, 0x00,
|
0x38, 0x00, 0x01, 0x00,
|
||||||
};
|
};
|
||||||
|
|
||||||
public static readonly byte[] StencilDrawToNonMsFragmentShaderSource = new byte[]
|
public static readonly byte[] StencilDrawToNonMsFragmentShaderSource = {
|
||||||
{
|
|
||||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x6A, 0x00, 0x00, 0x00,
|
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x6A, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||||
0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x45, 0x58, 0x54, 0x5F,
|
0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x45, 0x58, 0x54, 0x5F,
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -13,7 +11,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Int64,
|
Int64,
|
||||||
Float16,
|
Float16,
|
||||||
Float32,
|
Float32,
|
||||||
Float64
|
Float64,
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class SpecDescription
|
sealed class SpecDescription
|
||||||
|
@ -36,10 +34,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
structSize += typeSize;
|
structSize += typeSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info = new SpecializationInfo()
|
Info = new SpecializationInfo
|
||||||
{
|
{
|
||||||
DataSize = structSize,
|
DataSize = structSize,
|
||||||
MapEntryCount = (uint)count
|
MapEntryCount = (uint)count,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,10 +52,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
structSize = Math.Max(structSize, map[i].Offset + (uint)map[i].Size);
|
structSize = Math.Max(structSize, map[i].Offset + (uint)map[i].Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info = new SpecializationInfo()
|
Info = new SpecializationInfo
|
||||||
{
|
{
|
||||||
DataSize = structSize,
|
DataSize = structSize,
|
||||||
MapEntryCount = (uint)map.Length
|
MapEntryCount = (uint)map.Length,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +64,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SpecConstType.Int16 or SpecConstType.Float16 => 2,
|
SpecConstType.Int16 or SpecConstType.Float16 => 2,
|
||||||
SpecConstType.Bool32 or SpecConstType.Int32 or SpecConstType.Float32 => 4,
|
SpecConstType.Bool32 or SpecConstType.Int32 or SpecConstType.Float32 => 4,
|
||||||
SpecConstType.Int64 or SpecConstType.Float64 => 8,
|
SpecConstType.Int64 or SpecConstType.Float64 => 8,
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
_ => throw new ArgumentOutOfRangeException(nameof(type)),
|
||||||
};
|
};
|
||||||
|
|
||||||
private SpecDescription()
|
private SpecDescription()
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_freeSize = BufferSize;
|
_freeSize = BufferSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void PushData(CommandBufferPool cbp, CommandBufferScoped? cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
public void PushData(CommandBufferPool cbp, CommandBufferScoped? cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
bool isRender = cbs != null;
|
bool isRender = cbs != null;
|
||||||
CommandBufferScoped scoped = cbs ?? cbp.Rent();
|
CommandBufferScoped scoped = cbs ?? cbp.Rent();
|
||||||
|
@ -72,10 +72,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
int chunkSize = Math.Min(_freeSize, data.Length);
|
int chunkSize = Math.Min(_freeSize, data.Length);
|
||||||
|
|
||||||
PushDataImpl(scoped, dst, dstOffset, data.Slice(0, chunkSize));
|
PushDataImpl(scoped, dst, dstOffset, data[..chunkSize]);
|
||||||
|
|
||||||
dstOffset += chunkSize;
|
dstOffset += chunkSize;
|
||||||
data = data.Slice(chunkSize);
|
data = data[chunkSize..];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isRender)
|
if (!isRender)
|
||||||
|
@ -93,8 +93,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
int capacity = BufferSize - offset;
|
int capacity = BufferSize - offset;
|
||||||
if (capacity < data.Length)
|
if (capacity < data.Length)
|
||||||
{
|
{
|
||||||
_buffer.SetDataUnchecked(offset, data.Slice(0, capacity));
|
_buffer.SetDataUnchecked(offset, data[..capacity]);
|
||||||
_buffer.SetDataUnchecked(0, data.Slice(capacity));
|
_buffer.SetDataUnchecked(0, data[capacity..]);
|
||||||
|
|
||||||
BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, dstOffset, capacity);
|
BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, dstOffset, capacity);
|
||||||
BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, 0, dstOffset + capacity, data.Length - capacity);
|
BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, 0, dstOffset + capacity, data.Length - capacity);
|
||||||
|
@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pendingCopies.Enqueue(new PendingCopy(cbs.GetFence(), data.Length));
|
_pendingCopies.Enqueue(new PendingCopy(cbs.GetFence(), data.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe bool TryPushData(CommandBufferScoped cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
public bool TryPushData(CommandBufferScoped cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
if (data.Length > BufferSize)
|
if (data.Length > BufferSize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,13 +21,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ulong _firstHandle = 0;
|
private ulong _firstHandle;
|
||||||
|
|
||||||
private readonly VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
private readonly Device _device;
|
private readonly Device _device;
|
||||||
private List<SyncHandle> _handles;
|
private readonly List<SyncHandle> _handles;
|
||||||
private ulong FlushId;
|
private ulong _flushId;
|
||||||
private long WaitTicks;
|
private long _waitTicks;
|
||||||
|
|
||||||
public SyncManager(VulkanRenderer gd, Device device)
|
public SyncManager(VulkanRenderer gd, Device device)
|
||||||
{
|
{
|
||||||
|
@ -38,13 +38,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void RegisterFlush()
|
public void RegisterFlush()
|
||||||
{
|
{
|
||||||
FlushId++;
|
_flushId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(ulong id, bool strict)
|
public void Create(ulong id, bool strict)
|
||||||
{
|
{
|
||||||
ulong flushId = FlushId;
|
ulong flushId = _flushId;
|
||||||
MultiFenceHolder waitable = new MultiFenceHolder();
|
MultiFenceHolder waitable = new();
|
||||||
if (strict || _gd.InterruptAction == null)
|
if (strict || _gd.InterruptAction == null)
|
||||||
{
|
{
|
||||||
_gd.FlushAllCommands();
|
_gd.FlushAllCommands();
|
||||||
|
@ -58,11 +58,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_gd.CommandBufferPool.AddInUseWaitable(waitable);
|
_gd.CommandBufferPool.AddInUseWaitable(waitable);
|
||||||
}
|
}
|
||||||
|
|
||||||
SyncHandle handle = new SyncHandle
|
SyncHandle handle = new()
|
||||||
{
|
{
|
||||||
ID = id,
|
ID = id,
|
||||||
Waitable = waitable,
|
Waitable = waitable,
|
||||||
FlushId = flushId
|
FlushId = flushId,
|
||||||
};
|
};
|
||||||
|
|
||||||
lock (_handles)
|
lock (_handles)
|
||||||
|
@ -132,11 +132,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
long beforeTicks = Stopwatch.GetTimestamp();
|
long beforeTicks = Stopwatch.GetTimestamp();
|
||||||
|
|
||||||
if (result.NeedsFlush(FlushId))
|
if (result.NeedsFlush(_flushId))
|
||||||
{
|
{
|
||||||
_gd.InterruptAction(() =>
|
_gd.InterruptAction(() =>
|
||||||
{
|
{
|
||||||
if (result.NeedsFlush(FlushId))
|
if (result.NeedsFlush(_flushId))
|
||||||
{
|
{
|
||||||
_gd.FlushAllCommands();
|
_gd.FlushAllCommands();
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WaitTicks += Stopwatch.GetTimestamp() - beforeTicks;
|
_waitTicks += Stopwatch.GetTimestamp() - beforeTicks;
|
||||||
result.Signalled = true;
|
result.Signalled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
first = _handles.FirstOrDefault();
|
first = _handles.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first == null || first.NeedsFlush(FlushId)) break;
|
if (first == null || first.NeedsFlush(_flushId))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
bool signaled = first.Waitable.WaitForFences(_gd.Api, _device, 0);
|
bool signaled = first.Waitable.WaitForFences(_gd.Api, _device, 0);
|
||||||
if (signaled)
|
if (signaled)
|
||||||
|
@ -192,7 +195,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
first.Waitable = null;
|
first.Waitable = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// This sync handle and any following have not been reached yet.
|
// This sync handle and any following have not been reached yet.
|
||||||
break;
|
break;
|
||||||
|
@ -202,8 +206,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public long GetAndResetWaitTicks()
|
public long GetAndResetWaitTicks()
|
||||||
{
|
{
|
||||||
long result = WaitTicks;
|
long result = _waitTicks;
|
||||||
WaitTicks = 0;
|
_waitTicks = 0;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
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
|
||||||
|
@ -15,7 +16,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private int _offset;
|
private int _offset;
|
||||||
private int _size;
|
private int _size;
|
||||||
private Auto<DisposableBufferView> _bufferView;
|
private Auto<DisposableBufferView> _bufferView;
|
||||||
private Dictionary<GAL.Format, Auto<DisposableBufferView>> _selfManagedViews;
|
private Dictionary<Format, Auto<DisposableBufferView>> _selfManagedViews;
|
||||||
|
|
||||||
private int _bufferCount;
|
private int _bufferCount;
|
||||||
|
|
||||||
|
@ -131,15 +132,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public BufferView GetBufferView(CommandBufferScoped cbs)
|
public BufferView GetBufferView(CommandBufferScoped cbs)
|
||||||
{
|
{
|
||||||
if (_bufferView == null)
|
_bufferView ??= _gd.BufferManager.CreateView(_bufferHandle, VkFormat, _offset, _size, ReleaseImpl);
|
||||||
{
|
|
||||||
_bufferView = _gd.BufferManager.CreateView(_bufferHandle, VkFormat, _offset, _size, ReleaseImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _bufferView?.Get(cbs, _offset, _size).Value ?? default;
|
return _bufferView?.Get(cbs, _offset, _size).Value ?? default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BufferView GetBufferView(CommandBufferScoped cbs, GAL.Format format)
|
public BufferView GetBufferView(CommandBufferScoped cbs, Format format)
|
||||||
{
|
{
|
||||||
var vkFormat = FormatTable.GetFormat(format);
|
var vkFormat = FormatTable.GetFormat(format);
|
||||||
if (vkFormat == VkFormat)
|
if (vkFormat == VkFormat)
|
||||||
|
@ -156,7 +154,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (bufferView != null)
|
if (bufferView != null)
|
||||||
{
|
{
|
||||||
(_selfManagedViews ??= new Dictionary<GAL.Format, Auto<DisposableBufferView>>()).Add(format, bufferView);
|
(_selfManagedViews ??= new Dictionary<Format, Auto<DisposableBufferView>>()).Add(format, bufferView);
|
||||||
}
|
}
|
||||||
|
|
||||||
return bufferView?.Get(cbs, _offset, _size).Value ?? default;
|
return bufferView?.Get(cbs, _offset, _size).Value ?? default;
|
||||||
|
|
|
@ -80,12 +80,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
(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()
|
var region = new ImageBlit
|
||||||
{
|
{
|
||||||
SrcSubresource = srcSl,
|
SrcSubresource = srcSl,
|
||||||
SrcOffsets = srcOffsets,
|
SrcOffsets = srcOffsets,
|
||||||
DstSubresource = dstSl,
|
DstSubresource = dstSl,
|
||||||
DstOffsets = dstOffsets
|
DstOffsets = dstOffsets,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CmdBlitImage(commandBuffer, srcImage, ImageLayout.General, dstImage, ImageLayout.General, 1, region, filter);
|
api.CmdBlitImage(commandBuffer, srcImage, ImageLayout.General, dstImage, ImageLayout.General, 1, region, filter);
|
||||||
|
@ -219,21 +219,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
int dstZ;
|
int dstZ;
|
||||||
int dstLayer;
|
int dstLayer;
|
||||||
int dstDepth;
|
|
||||||
int dstLayers;
|
int dstLayers;
|
||||||
|
|
||||||
if (dstInfo.Target == Target.Texture3D)
|
if (dstInfo.Target == Target.Texture3D)
|
||||||
{
|
{
|
||||||
dstZ = dstDepthOrLayer;
|
dstZ = dstDepthOrLayer;
|
||||||
dstLayer = 0;
|
dstLayer = 0;
|
||||||
dstDepth = depthOrLayers;
|
|
||||||
dstLayers = 1;
|
dstLayers = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dstZ = 0;
|
dstZ = 0;
|
||||||
dstLayer = dstDepthOrLayer;
|
dstLayer = dstDepthOrLayer;
|
||||||
dstDepth = 1;
|
|
||||||
dstLayers = depthOrLayers;
|
dstLayers = depthOrLayers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,20 +363,20 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var dsAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 0, ImageLayout.General);
|
var dsAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 0, ImageLayout.General);
|
||||||
var dsResolveAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 1, ImageLayout.General);
|
var dsResolveAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 1, ImageLayout.General);
|
||||||
|
|
||||||
var subpassDsResolve = new SubpassDescriptionDepthStencilResolve()
|
var subpassDsResolve = new SubpassDescriptionDepthStencilResolve
|
||||||
{
|
{
|
||||||
SType = StructureType.SubpassDescriptionDepthStencilResolve,
|
SType = StructureType.SubpassDescriptionDepthStencilResolve,
|
||||||
PDepthStencilResolveAttachment = &dsResolveAttachmentReference,
|
PDepthStencilResolveAttachment = &dsResolveAttachmentReference,
|
||||||
DepthResolveMode = ResolveModeFlags.SampleZeroBit,
|
DepthResolveMode = ResolveModeFlags.SampleZeroBit,
|
||||||
StencilResolveMode = ResolveModeFlags.SampleZeroBit
|
StencilResolveMode = ResolveModeFlags.SampleZeroBit,
|
||||||
};
|
};
|
||||||
|
|
||||||
var subpass = new SubpassDescription2()
|
var subpass = new SubpassDescription2
|
||||||
{
|
{
|
||||||
SType = StructureType.SubpassDescription2,
|
SType = StructureType.SubpassDescription2,
|
||||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||||
PDepthStencilAttachment = &dsAttachmentReference,
|
PDepthStencilAttachment = &dsAttachmentReference,
|
||||||
PNext = &subpassDsResolve
|
PNext = &subpassDsResolve,
|
||||||
};
|
};
|
||||||
|
|
||||||
AttachmentDescription2[] attachmentDescs = new AttachmentDescription2[2];
|
AttachmentDescription2[] attachmentDescs = new AttachmentDescription2[2];
|
||||||
|
@ -414,7 +411,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
fixed (AttachmentDescription2* pAttachmentDescs = attachmentDescs)
|
fixed (AttachmentDescription2* pAttachmentDescs = attachmentDescs)
|
||||||
{
|
{
|
||||||
var renderPassCreateInfo = new RenderPassCreateInfo2()
|
var renderPassCreateInfo = new RenderPassCreateInfo2
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassCreateInfo2,
|
SType = StructureType.RenderPassCreateInfo2,
|
||||||
PAttachments = pAttachmentDescs,
|
PAttachments = pAttachmentDescs,
|
||||||
|
@ -422,7 +419,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PSubpasses = &subpass,
|
PSubpasses = &subpass,
|
||||||
SubpassCount = 1,
|
SubpassCount = 1,
|
||||||
PDependencies = &subpassDependency,
|
PDependencies = &subpassDependency,
|
||||||
DependencyCount = 1
|
DependencyCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateRenderPass2(device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
gd.Api.CreateRenderPass2(device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
||||||
|
@ -437,7 +434,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
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()
|
var framebufferCreateInfo = new FramebufferCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.FramebufferCreateInfo,
|
SType = StructureType.FramebufferCreateInfo,
|
||||||
RenderPass = rp.Get(cbs).Value,
|
RenderPass = rp.Get(cbs).Value,
|
||||||
|
@ -445,23 +442,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PAttachments = attachments,
|
PAttachments = attachments,
|
||||||
Width = (uint)src.Width,
|
Width = (uint)src.Width,
|
||||||
Height = (uint)src.Height,
|
Height = (uint)src.Height,
|
||||||
Layers = (uint)src.Layers
|
Layers = (uint)src.Layers,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateFramebuffer(device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
gd.Api.CreateFramebuffer(device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
||||||
using var fb = new Auto<DisposableFramebuffer>(new DisposableFramebuffer(gd.Api, device, framebuffer), null, new[] { srcView, dstView });
|
using var 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));
|
var renderArea = new Rect2D(null, new Extent2D((uint)src.Info.Width, (uint)src.Info.Height));
|
||||||
var clearValue = new ClearValue();
|
var clearValue = new ClearValue();
|
||||||
|
|
||||||
var renderPassBeginInfo = new RenderPassBeginInfo()
|
var renderPassBeginInfo = new RenderPassBeginInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.RenderPassBeginInfo,
|
SType = StructureType.RenderPassBeginInfo,
|
||||||
RenderPass = rp.Get(cbs).Value,
|
RenderPass = rp.Get(cbs).Value,
|
||||||
Framebuffer = fb.Get(cbs).Value,
|
Framebuffer = fb.Get(cbs).Value,
|
||||||
RenderArea = renderArea,
|
RenderArea = renderArea,
|
||||||
PClearValues = &clearValue,
|
PClearValues = &clearValue,
|
||||||
ClearValueCount = 1
|
ClearValueCount = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The resolve operation happens at the end of the subpass, so let's just do a begin/end
|
// The resolve operation happens at the end of the subpass, so let's just do a begin/end
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||||
using VkFormat = Silk.NET.Vulkan.Format;
|
using VkFormat = Silk.NET.Vulkan.Format;
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly Auto<MemoryAllocation> _allocationAuto;
|
private readonly Auto<MemoryAllocation> _allocationAuto;
|
||||||
private Auto<MemoryAllocation> _foreignAllocationAuto;
|
private Auto<MemoryAllocation> _foreignAllocationAuto;
|
||||||
|
|
||||||
private Dictionary<GAL.Format, TextureStorage> _aliasedStorages;
|
private Dictionary<Format, TextureStorage> _aliasedStorages;
|
||||||
|
|
||||||
private AccessFlags _lastModificationAccess;
|
private AccessFlags _lastModificationAccess;
|
||||||
private PipelineStageFlags _lastModificationStage;
|
private PipelineStageFlags _lastModificationStage;
|
||||||
|
@ -50,7 +51,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private PipelineStageFlags _lastReadStage;
|
private PipelineStageFlags _lastReadStage;
|
||||||
|
|
||||||
private int _viewsCount;
|
private int _viewsCount;
|
||||||
private ulong _size;
|
private readonly ulong _size;
|
||||||
|
|
||||||
public VkFormat VkFormat { get; }
|
public VkFormat VkFormat { get; }
|
||||||
public float ScaleFactor { get; }
|
public float ScaleFactor { get; }
|
||||||
|
@ -98,7 +99,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
flags |= ImageCreateFlags.Create2DArrayCompatibleBit;
|
flags |= ImageCreateFlags.Create2DArrayCompatibleBit;
|
||||||
}
|
}
|
||||||
|
|
||||||
var imageCreateInfo = new ImageCreateInfo()
|
var imageCreateInfo = new ImageCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageCreateInfo,
|
SType = StructureType.ImageCreateInfo,
|
||||||
ImageType = type,
|
ImageType = type,
|
||||||
|
@ -111,7 +112,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Usage = usage,
|
Usage = usage,
|
||||||
SharingMode = SharingMode.Exclusive,
|
SharingMode = SharingMode.Exclusive,
|
||||||
InitialLayout = ImageLayout.Undefined,
|
InitialLayout = ImageLayout.Undefined,
|
||||||
Flags = flags
|
Flags = flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError();
|
gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError();
|
||||||
|
@ -150,27 +151,27 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureStorage CreateAliasedColorForDepthStorageUnsafe(GAL.Format format)
|
public TextureStorage CreateAliasedColorForDepthStorageUnsafe(Format format)
|
||||||
{
|
{
|
||||||
var colorFormat = format switch
|
var colorFormat = format switch
|
||||||
{
|
{
|
||||||
GAL.Format.S8Uint => GAL.Format.R8Unorm,
|
Format.S8Uint => Format.R8Unorm,
|
||||||
GAL.Format.D16Unorm => GAL.Format.R16Unorm,
|
Format.D16Unorm => Format.R16Unorm,
|
||||||
GAL.Format.S8UintD24Unorm => GAL.Format.R8G8B8A8Unorm,
|
Format.S8UintD24Unorm => Format.R8G8B8A8Unorm,
|
||||||
GAL.Format.D32Float => GAL.Format.R32Float,
|
Format.D32Float => Format.R32Float,
|
||||||
GAL.Format.D24UnormS8Uint => GAL.Format.R8G8B8A8Unorm,
|
Format.D24UnormS8Uint => Format.R8G8B8A8Unorm,
|
||||||
GAL.Format.D32FloatS8Uint => GAL.Format.R32G32Float,
|
Format.D32FloatS8Uint => Format.R32G32Float,
|
||||||
_ => throw new ArgumentException($"\"{format}\" is not a supported depth or stencil format.")
|
_ => throw new ArgumentException($"\"{format}\" is not a supported depth or stencil format."),
|
||||||
};
|
};
|
||||||
|
|
||||||
return CreateAliasedStorageUnsafe(colorFormat);
|
return CreateAliasedStorageUnsafe(colorFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureStorage CreateAliasedStorageUnsafe(GAL.Format format)
|
public TextureStorage CreateAliasedStorageUnsafe(Format format)
|
||||||
{
|
{
|
||||||
if (_aliasedStorages == null || !_aliasedStorages.TryGetValue(format, out var storage))
|
if (_aliasedStorages == null || !_aliasedStorages.TryGetValue(format, out var storage))
|
||||||
{
|
{
|
||||||
_aliasedStorages ??= new Dictionary<GAL.Format, TextureStorage>();
|
_aliasedStorages ??= new Dictionary<Format, TextureStorage>();
|
||||||
|
|
||||||
var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel);
|
var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel);
|
||||||
|
|
||||||
|
@ -182,14 +183,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return storage;
|
return storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextureCreateInfo NewCreateInfoWith(ref TextureCreateInfo info, GAL.Format format, int bytesPerPixel)
|
public static TextureCreateInfo NewCreateInfoWith(ref TextureCreateInfo info, Format format, int bytesPerPixel)
|
||||||
{
|
{
|
||||||
return NewCreateInfoWith(ref info, format, bytesPerPixel, info.Width, info.Height);
|
return NewCreateInfoWith(ref info, format, bytesPerPixel, info.Width, info.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextureCreateInfo NewCreateInfoWith(
|
public static TextureCreateInfo NewCreateInfoWith(
|
||||||
ref TextureCreateInfo info,
|
ref TextureCreateInfo info,
|
||||||
GAL.Format format,
|
Format format,
|
||||||
int bytesPerPixel,
|
int bytesPerPixel,
|
||||||
int width,
|
int width,
|
||||||
int height)
|
int height)
|
||||||
|
@ -262,7 +263,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, (uint)_info.Levels, 0, (uint)_info.GetLayers());
|
var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, (uint)_info.Levels, 0, (uint)_info.GetLayers());
|
||||||
|
|
||||||
var barrier = new ImageMemoryBarrier()
|
var barrier = new ImageMemoryBarrier
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageMemoryBarrier,
|
SType = StructureType.ImageMemoryBarrier,
|
||||||
SrcAccessMask = 0,
|
SrcAccessMask = 0,
|
||||||
|
@ -272,7 +273,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
Image = _imageAuto.Get(cbs).Value,
|
Image = _imageAuto.Get(cbs).Value,
|
||||||
SubresourceRange = subresourceRange
|
SubresourceRange = subresourceRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.Api.CmdPipelineBarrier(
|
_gd.Api.CmdPipelineBarrier(
|
||||||
|
@ -293,7 +294,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageUsageFlags GetImageUsage(GAL.Format format, Target target, bool supportsMsStorage)
|
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage)
|
||||||
{
|
{
|
||||||
var usage = DefaultUsageFlags;
|
var usage = DefaultUsageFlags;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ using Ryujinx.Graphics.GAL;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Format = Ryujinx.Graphics.GAL.Format;
|
||||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||||
using VkFormat = Silk.NET.Vulkan.Format;
|
using VkFormat = Silk.NET.Vulkan.Format;
|
||||||
|
|
||||||
|
@ -18,9 +19,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private readonly Auto<DisposableImageView> _imageViewDraw;
|
private readonly Auto<DisposableImageView> _imageViewDraw;
|
||||||
private readonly Auto<DisposableImageView> _imageViewIdentity;
|
private readonly Auto<DisposableImageView> _imageViewIdentity;
|
||||||
private readonly Auto<DisposableImageView> _imageView2dArray;
|
private readonly Auto<DisposableImageView> _imageView2dArray;
|
||||||
private Dictionary<GAL.Format, TextureView> _selfManagedViews;
|
private Dictionary<Format, TextureView> _selfManagedViews;
|
||||||
|
|
||||||
private TextureCreateInfo _info;
|
private readonly TextureCreateInfo _info;
|
||||||
|
|
||||||
public TextureCreateInfo Info => _info;
|
public TextureCreateInfo Info => _info;
|
||||||
|
|
||||||
|
@ -68,16 +69,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
var swizzleB = info.SwizzleB.Convert();
|
var swizzleB = info.SwizzleB.Convert();
|
||||||
var swizzleA = info.SwizzleA.Convert();
|
var swizzleA = info.SwizzleA.Convert();
|
||||||
|
|
||||||
if (info.Format == GAL.Format.R5G5B5A1Unorm ||
|
if (info.Format == Format.R5G5B5A1Unorm ||
|
||||||
info.Format == GAL.Format.R5G5B5X1Unorm ||
|
info.Format == Format.R5G5B5X1Unorm ||
|
||||||
info.Format == GAL.Format.R5G6B5Unorm)
|
info.Format == Format.R5G6B5Unorm)
|
||||||
{
|
{
|
||||||
var temp = swizzleR;
|
(swizzleB, swizzleR) = (swizzleR, swizzleB);
|
||||||
|
|
||||||
swizzleR = swizzleB;
|
|
||||||
swizzleB = temp;
|
|
||||||
}
|
}
|
||||||
else if (VkFormat == VkFormat.R4G4B4A4UnormPack16 || info.Format == GAL.Format.A1B5G5R5Unorm)
|
else if (VkFormat == VkFormat.R4G4B4A4UnormPack16 || info.Format == Format.A1B5G5R5Unorm)
|
||||||
{
|
{
|
||||||
var tempB = swizzleB;
|
var tempB = swizzleB;
|
||||||
var tempA = swizzleA;
|
var tempA = swizzleA;
|
||||||
|
@ -98,13 +96,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
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 usage = new ImageViewUsageCreateInfo()
|
var usage = new ImageViewUsageCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageViewUsageCreateInfo,
|
SType = StructureType.ImageViewUsageCreateInfo,
|
||||||
Usage = usageFlags
|
Usage = usageFlags,
|
||||||
};
|
};
|
||||||
|
|
||||||
var imageCreateInfo = new ImageViewCreateInfo()
|
var imageCreateInfo = new ImageViewCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageViewCreateInfo,
|
SType = StructureType.ImageViewCreateInfo,
|
||||||
Image = storage.GetImageForViewCreation(),
|
Image = storage.GetImageForViewCreation(),
|
||||||
|
@ -112,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Format = format,
|
Format = format,
|
||||||
Components = cm,
|
Components = cm,
|
||||||
SubresourceRange = sr,
|
SubresourceRange = sr,
|
||||||
PNext = &usage
|
PNext = &usage,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateImageView(device, imageCreateInfo, null, out var imageView).ThrowOnError();
|
gd.Api.CreateImageView(device, imageCreateInfo, null, out var imageView).ThrowOnError();
|
||||||
|
@ -354,7 +352,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitSrcBit, srcFormat) &&
|
|
||||||
|
if (_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitSrcBit, srcFormat) &&
|
||||||
_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitDstBit, dstFormat))
|
_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitDstBit, dstFormat))
|
||||||
{
|
{
|
||||||
TextureCopy.Blit(
|
TextureCopy.Blit(
|
||||||
|
@ -444,7 +443,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
int layers,
|
int layers,
|
||||||
int levels)
|
int levels)
|
||||||
{
|
{
|
||||||
ImageMemoryBarrier memoryBarrier = new ImageMemoryBarrier()
|
ImageMemoryBarrier memoryBarrier = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageMemoryBarrier,
|
SType = StructureType.ImageMemoryBarrier,
|
||||||
SrcAccessMask = srcAccessMask,
|
SrcAccessMask = srcAccessMask,
|
||||||
|
@ -454,7 +453,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Image = image,
|
Image = image,
|
||||||
OldLayout = ImageLayout.General,
|
OldLayout = ImageLayout.General,
|
||||||
NewLayout = ImageLayout.General,
|
NewLayout = ImageLayout.General,
|
||||||
SubresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, (uint)levels, (uint)firstLayer, (uint)layers)
|
SubresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, (uint)levels, (uint)firstLayer, (uint)layers),
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CmdPipelineBarrier(
|
api.CmdPipelineBarrier(
|
||||||
|
@ -470,7 +469,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
memoryBarrier);
|
memoryBarrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureView GetView(GAL.Format format)
|
public TextureView GetView(Format format)
|
||||||
{
|
{
|
||||||
if (format == Info.Format)
|
if (format == Info.Format)
|
||||||
{
|
{
|
||||||
|
@ -499,7 +498,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Info.SwizzleB,
|
Info.SwizzleB,
|
||||||
Info.SwizzleA), 0, 0);
|
Info.SwizzleA), 0, 0);
|
||||||
|
|
||||||
(_selfManagedViews ??= new Dictionary<GAL.Format, TextureView>()).Add(format, view);
|
(_selfManagedViews ??= new Dictionary<Format, TextureView>()).Add(format, view);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
@ -543,11 +542,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(_gd.CommandBufferPool, resources.GetFlushBuffer()));
|
return PinnedSpan<byte>.UnsafeFromSpan(GetData(_gd.CommandBufferPool, resources.GetFlushBuffer()));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer()));
|
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer()));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public PinnedSpan<byte> GetData(int layer, int level)
|
public PinnedSpan<byte> GetData(int layer, int level)
|
||||||
{
|
{
|
||||||
|
@ -559,11 +556,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(_gd.CommandBufferPool, resources.GetFlushBuffer(), layer, level));
|
return PinnedSpan<byte>.UnsafeFromSpan(GetData(_gd.CommandBufferPool, resources.GetFlushBuffer(), layer, level));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer(), layer, level));
|
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer(), layer, level));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
||||||
{
|
{
|
||||||
|
@ -686,11 +681,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GAL.Format GetCompatibleGalFormat(GAL.Format format)
|
private Format GetCompatibleGalFormat(Format format)
|
||||||
{
|
{
|
||||||
if (NeedsD24S8Conversion())
|
if (NeedsD24S8Conversion())
|
||||||
{
|
{
|
||||||
return GAL.Format.D32FloatS8Uint;
|
return Format.D32FloatS8Uint;
|
||||||
}
|
}
|
||||||
|
|
||||||
return format;
|
return format;
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Broadcom,
|
Broadcom,
|
||||||
Qualcomm,
|
Qualcomm,
|
||||||
Apple,
|
Apple,
|
||||||
Unknown
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
static partial class VendorUtils
|
static partial class VendorUtils
|
||||||
|
@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
0x14E4 => Vendor.Broadcom,
|
0x14E4 => Vendor.Broadcom,
|
||||||
0x8086 => Vendor.Intel,
|
0x8086 => Vendor.Intel,
|
||||||
0x5143 => Vendor.Qualcomm,
|
0x5143 => Vendor.Qualcomm,
|
||||||
_ => Vendor.Unknown
|
_ => Vendor.Unknown,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
0x10004 => "Codeplay Software Ltd.",
|
0x10004 => "Codeplay Software Ltd.",
|
||||||
0x10005 => "Mesa",
|
0x10005 => "Mesa",
|
||||||
0x10006 => "PoCL",
|
0x10006 => "PoCL",
|
||||||
_ => $"0x{id:X}"
|
_ => $"0x{id:X}",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
using BufferHandle = Ryujinx.Graphics.GAL.BufferHandle;
|
using Ryujinx.Graphics.GAL;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
internal struct VertexBufferState
|
internal struct VertexBufferState
|
||||||
{
|
{
|
||||||
public static VertexBufferState Null => new VertexBufferState(null, 0, 0, 0);
|
public static VertexBufferState Null => new(null, 0, 0, 0);
|
||||||
|
|
||||||
private readonly int _offset;
|
private readonly int _offset;
|
||||||
private readonly int _size;
|
private readonly int _size;
|
||||||
|
@ -74,8 +74,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
autoBuffer = gd.BufferManager.GetBuffer(cbs.CommandBuffer, _handle, false, out int size);
|
autoBuffer = gd.BufferManager.GetBuffer(cbs.CommandBuffer, _handle, false, out int size);
|
||||||
|
|
||||||
// The original stride must be reapplied in case it was rewritten.
|
// The original stride must be reapplied in case it was rewritten.
|
||||||
|
@ -86,7 +85,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
autoBuffer = null;
|
autoBuffer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (autoBuffer != null)
|
if (autoBuffer != null)
|
||||||
{
|
{
|
||||||
|
@ -96,12 +94,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BoundEquals(Auto<DisposableBuffer> buffer)
|
public readonly bool BoundEquals(Auto<DisposableBuffer> buffer)
|
||||||
{
|
{
|
||||||
return _buffer == buffer;
|
return _buffer == buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Matches(Auto<DisposableBuffer> buffer, int descriptorIndex, int offset, int size, int stride = 0)
|
public readonly bool Matches(Auto<DisposableBuffer> buffer, int descriptorIndex, int offset, int size, int stride = 0)
|
||||||
{
|
{
|
||||||
return _buffer == buffer && DescriptorIndex == descriptorIndex && _offset == offset && _size == size && _stride == stride;
|
return _buffer == buffer && DescriptorIndex == descriptorIndex && _offset == offset && _size == size && _stride == stride;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +115,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public readonly void Dispose()
|
||||||
{
|
{
|
||||||
// Only dispose if this buffer is not refetched on each bind.
|
// Only dispose if this buffer is not refetched on each bind.
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
using Silk.NET.Vulkan;
|
using System;
|
||||||
using System;
|
|
||||||
|
|
||||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
internal class VertexBufferUpdater : IDisposable
|
internal class VertexBufferUpdater : IDisposable
|
||||||
{
|
{
|
||||||
private VulkanRenderer _gd;
|
private readonly VulkanRenderer _gd;
|
||||||
|
|
||||||
private uint _baseBinding;
|
private uint _baseBinding;
|
||||||
private uint _count;
|
private uint _count;
|
||||||
|
|
||||||
private NativeArray<VkBuffer> _buffers;
|
private readonly NativeArray<VkBuffer> _buffers;
|
||||||
private NativeArray<ulong> _offsets;
|
private readonly NativeArray<ulong> _offsets;
|
||||||
private NativeArray<ulong> _sizes;
|
private readonly NativeArray<ulong> _sizes;
|
||||||
private NativeArray<ulong> _strides;
|
private readonly NativeArray<ulong> _strides;
|
||||||
|
|
||||||
public VertexBufferUpdater(VulkanRenderer gd)
|
public VertexBufferUpdater(VulkanRenderer gd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,8 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
class VulkanDebugMessenger : IDisposable
|
class VulkanDebugMessenger : IDisposable
|
||||||
{
|
{
|
||||||
private static string[] _excludedMessages = new string[]
|
private static readonly string[] _excludedMessages = {
|
||||||
{
|
|
||||||
// NOTE: Done on purpose right now.
|
// NOTE: Done on purpose right now.
|
||||||
"UNASSIGNED-CoreValidation-Shader-OutputNotConsumed",
|
"UNASSIGNED-CoreValidation-Shader-OutputNotConsumed",
|
||||||
// TODO: Figure out if fixable
|
// TODO: Figure out if fixable
|
||||||
|
@ -19,7 +18,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// TODO: Might be worth looking into making this happy to possibly optimize copies.
|
// TODO: Might be worth looking into making this happy to possibly optimize copies.
|
||||||
"UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout",
|
"UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout",
|
||||||
// TODO: Fix this, it's causing too much noise right now.
|
// TODO: Fix this, it's causing too much noise right now.
|
||||||
"VUID-VkSubpassDependency-srcSubpass-00867"
|
"VUID-VkSubpassDependency-srcSubpass-00867",
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly Vk _api;
|
private readonly Vk _api;
|
||||||
|
@ -59,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
GraphicsDebugLevel.All => DebugUtilsMessageTypeFlagsEXT.GeneralBitExt |
|
GraphicsDebugLevel.All => DebugUtilsMessageTypeFlagsEXT.GeneralBitExt |
|
||||||
DebugUtilsMessageTypeFlagsEXT.ValidationBitExt |
|
DebugUtilsMessageTypeFlagsEXT.ValidationBitExt |
|
||||||
DebugUtilsMessageTypeFlagsEXT.PerformanceBitExt,
|
DebugUtilsMessageTypeFlagsEXT.PerformanceBitExt,
|
||||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\".")
|
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
var messageSeverity = _logLevel switch
|
var messageSeverity = _logLevel switch
|
||||||
|
@ -71,14 +70,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
DebugUtilsMessageSeverityFlagsEXT.WarningBitExt |
|
DebugUtilsMessageSeverityFlagsEXT.WarningBitExt |
|
||||||
DebugUtilsMessageSeverityFlagsEXT.VerboseBitExt |
|
DebugUtilsMessageSeverityFlagsEXT.VerboseBitExt |
|
||||||
DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt,
|
DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt,
|
||||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\".")
|
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
||||||
};
|
};
|
||||||
|
|
||||||
var debugUtilsMessengerCreateInfo = new DebugUtilsMessengerCreateInfoEXT()
|
var debugUtilsMessengerCreateInfo = new DebugUtilsMessengerCreateInfoEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.DebugUtilsMessengerCreateInfoExt,
|
SType = StructureType.DebugUtilsMessengerCreateInfoExt,
|
||||||
MessageType = messageType,
|
MessageType = messageType,
|
||||||
MessageSeverity = messageSeverity
|
MessageSeverity = messageSeverity,
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe
|
unsafe
|
||||||
|
|
|
@ -14,14 +14,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public unsafe static class VulkanInitialization
|
public unsafe static class VulkanInitialization
|
||||||
{
|
{
|
||||||
private const uint InvalidIndex = uint.MaxValue;
|
private const uint InvalidIndex = uint.MaxValue;
|
||||||
private static uint MinimalVulkanVersion = Vk.Version11.Value;
|
private static readonly uint _minimalVulkanVersion = Vk.Version11.Value;
|
||||||
private static uint MinimalInstanceVulkanVersion = Vk.Version12.Value;
|
private static readonly uint _minimalInstanceVulkanVersion = Vk.Version12.Value;
|
||||||
private static uint MaximumVulkanVersion = Vk.Version12.Value;
|
private static readonly uint _maximumVulkanVersion = Vk.Version12.Value;
|
||||||
private const string AppName = "Ryujinx.Graphics.Vulkan";
|
private const string AppName = "Ryujinx.Graphics.Vulkan";
|
||||||
private const int QueuesCount = 2;
|
private const int QueuesCount = 2;
|
||||||
|
|
||||||
private static readonly string[] _desirableExtensions = new string[]
|
private static readonly string[] _desirableExtensions = {
|
||||||
{
|
|
||||||
ExtConditionalRendering.ExtensionName,
|
ExtConditionalRendering.ExtensionName,
|
||||||
ExtExtendedDynamicState.ExtensionName,
|
ExtExtendedDynamicState.ExtensionName,
|
||||||
ExtTransformFeedback.ExtensionName,
|
ExtTransformFeedback.ExtensionName,
|
||||||
|
@ -42,12 +41,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
"VK_NV_geometry_shader_passthrough",
|
"VK_NV_geometry_shader_passthrough",
|
||||||
"VK_NV_viewport_array2",
|
"VK_NV_viewport_array2",
|
||||||
"VK_EXT_depth_clip_control",
|
"VK_EXT_depth_clip_control",
|
||||||
"VK_KHR_portability_subset" // As per spec, we should enable this if present.
|
"VK_KHR_portability_subset", // As per spec, we should enable this if present.
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly string[] _requiredExtensions = new string[]
|
private static readonly string[] _requiredExtensions = {
|
||||||
{
|
KhrSwapchain.ExtensionName,
|
||||||
KhrSwapchain.ExtensionName
|
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static VulkanInstance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions)
|
internal static VulkanInstance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions)
|
||||||
|
@ -89,7 +87,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ApplicationVersion = 1,
|
ApplicationVersion = 1,
|
||||||
PEngineName = (byte*)appName,
|
PEngineName = (byte*)appName,
|
||||||
EngineVersion = 1,
|
EngineVersion = 1,
|
||||||
ApiVersion = MaximumVulkanVersion
|
ApiVersion = _maximumVulkanVersion,
|
||||||
};
|
};
|
||||||
|
|
||||||
IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];
|
IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];
|
||||||
|
@ -112,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PpEnabledExtensionNames = (byte**)ppEnabledExtensions,
|
PpEnabledExtensionNames = (byte**)ppEnabledExtensions,
|
||||||
PpEnabledLayerNames = (byte**)ppEnabledLayers,
|
PpEnabledLayerNames = (byte**)ppEnabledLayers,
|
||||||
EnabledExtensionCount = (uint)enabledExtensions.Length,
|
EnabledExtensionCount = (uint)enabledExtensions.Length,
|
||||||
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 var instance);
|
||||||
|
@ -169,7 +167,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ApplicationVersion = 1,
|
ApplicationVersion = 1,
|
||||||
PEngineName = (byte*)appName,
|
PEngineName = (byte*)appName,
|
||||||
EngineVersion = 1,
|
EngineVersion = 1,
|
||||||
ApiVersion = MaximumVulkanVersion
|
ApiVersion = _maximumVulkanVersion,
|
||||||
};
|
};
|
||||||
|
|
||||||
var instanceCreateInfo = new InstanceCreateInfo
|
var instanceCreateInfo = new InstanceCreateInfo
|
||||||
|
@ -179,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PpEnabledExtensionNames = null,
|
PpEnabledExtensionNames = null,
|
||||||
PpEnabledLayerNames = null,
|
PpEnabledLayerNames = null,
|
||||||
EnabledExtensionCount = 0,
|
EnabledExtensionCount = 0,
|
||||||
EnabledLayerCount = 0
|
EnabledLayerCount = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out var rawInstance);
|
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out var rawInstance);
|
||||||
|
@ -192,18 +190,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
// We currently assume that the instance is compatible with Vulkan 1.2
|
// We currently assume that the instance is compatible with Vulkan 1.2
|
||||||
// TODO: Remove this once we relax our initialization codepaths.
|
// TODO: Remove this once we relax our initialization codepaths.
|
||||||
if (instance.InstanceVersion < MinimalInstanceVulkanVersion)
|
if (instance.InstanceVersion < _minimalInstanceVulkanVersion)
|
||||||
{
|
{
|
||||||
return Array.Empty<DeviceInfo>();
|
return Array.Empty<DeviceInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.EnumeratePhysicalDevices(out VulkanPhysicalDevice[] physicalDevices).ThrowOnError();
|
instance.EnumeratePhysicalDevices(out VulkanPhysicalDevice[] physicalDevices).ThrowOnError();
|
||||||
|
|
||||||
List<DeviceInfo> deviceInfos = new List<DeviceInfo>();
|
List<DeviceInfo> deviceInfos = new();
|
||||||
|
|
||||||
foreach (VulkanPhysicalDevice physicalDevice in physicalDevices)
|
foreach (VulkanPhysicalDevice physicalDevice in physicalDevices)
|
||||||
{
|
{
|
||||||
if (physicalDevice.PhysicalDeviceProperties.ApiVersion < MinimalVulkanVersion)
|
if (physicalDevice.PhysicalDeviceProperties.ApiVersion < _minimalVulkanVersion)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -278,33 +276,33 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
queuePriorities[i] = 1f;
|
queuePriorities[i] = 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
var queueCreateInfo = new DeviceQueueCreateInfo()
|
var queueCreateInfo = new DeviceQueueCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DeviceQueueCreateInfo,
|
SType = StructureType.DeviceQueueCreateInfo,
|
||||||
QueueFamilyIndex = queueFamilyIndex,
|
QueueFamilyIndex = queueFamilyIndex,
|
||||||
QueueCount = queueCount,
|
QueueCount = queueCount,
|
||||||
PQueuePriorities = queuePriorities
|
PQueuePriorities = queuePriorities,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool useRobustBufferAccess = VendorUtils.FromId(physicalDevice.PhysicalDeviceProperties.VendorID) == Vendor.Nvidia;
|
bool useRobustBufferAccess = VendorUtils.FromId(physicalDevice.PhysicalDeviceProperties.VendorID) == Vendor.Nvidia;
|
||||||
|
|
||||||
PhysicalDeviceFeatures2 features2 = new PhysicalDeviceFeatures2()
|
PhysicalDeviceFeatures2 features2 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceFeatures2
|
SType = StructureType.PhysicalDeviceFeatures2,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new PhysicalDeviceVulkan11Features()
|
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||||
PNext = features2.PNext
|
PNext = features2.PNext,
|
||||||
};
|
};
|
||||||
|
|
||||||
features2.PNext = &supportedFeaturesVk11;
|
features2.PNext = &supportedFeaturesVk11;
|
||||||
|
|
||||||
PhysicalDeviceCustomBorderColorFeaturesEXT supportedFeaturesCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
PhysicalDeviceCustomBorderColorFeaturesEXT supportedFeaturesCustomBorderColor = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||||
PNext = features2.PNext
|
PNext = features2.PNext,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_custom_border_color"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_custom_border_color"))
|
||||||
|
@ -312,10 +310,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
features2.PNext = &supportedFeaturesCustomBorderColor;
|
features2.PNext = &supportedFeaturesCustomBorderColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT supportedFeaturesPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT()
|
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT supportedFeaturesPrimitiveTopologyListRestart = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
||||||
PNext = features2.PNext
|
PNext = features2.PNext,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
||||||
|
@ -323,10 +321,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
features2.PNext = &supportedFeaturesPrimitiveTopologyListRestart;
|
features2.PNext = &supportedFeaturesPrimitiveTopologyListRestart;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceTransformFeedbackFeaturesEXT supportedFeaturesTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
PhysicalDeviceTransformFeedbackFeaturesEXT supportedFeaturesTransformFeedback = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||||
PNext = features2.PNext
|
PNext = features2.PNext,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName))
|
if (physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName))
|
||||||
|
@ -334,9 +332,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
features2.PNext = &supportedFeaturesTransformFeedback;
|
features2.PNext = &supportedFeaturesTransformFeedback;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt
|
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_robustness2"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_robustness2"))
|
||||||
|
@ -346,10 +344,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
features2.PNext = &supportedFeaturesRobustness2;
|
features2.PNext = &supportedFeaturesRobustness2;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceDepthClipControlFeaturesEXT supportedFeaturesDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
|
PhysicalDeviceDepthClipControlFeaturesEXT supportedFeaturesDepthClipControl = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
||||||
PNext = features2.PNext
|
PNext = features2.PNext,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control"))
|
||||||
|
@ -361,7 +359,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var supportedFeatures = features2.Features;
|
var supportedFeatures = features2.Features;
|
||||||
|
|
||||||
var features = new PhysicalDeviceFeatures()
|
var features = new PhysicalDeviceFeatures
|
||||||
{
|
{
|
||||||
DepthBiasClamp = supportedFeatures.DepthBiasClamp,
|
DepthBiasClamp = supportedFeatures.DepthBiasClamp,
|
||||||
DepthClamp = supportedFeatures.DepthClamp,
|
DepthClamp = supportedFeatures.DepthClamp,
|
||||||
|
@ -383,7 +381,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// ShaderStorageImageWriteWithoutFormat = true,
|
// ShaderStorageImageWriteWithoutFormat = true,
|
||||||
TessellationShader = supportedFeatures.TessellationShader,
|
TessellationShader = supportedFeatures.TessellationShader,
|
||||||
VertexPipelineStoresAndAtomics = supportedFeatures.VertexPipelineStoresAndAtomics,
|
VertexPipelineStoresAndAtomics = supportedFeatures.VertexPipelineStoresAndAtomics,
|
||||||
RobustBufferAccess = useRobustBufferAccess
|
RobustBufferAccess = useRobustBufferAccess,
|
||||||
};
|
};
|
||||||
|
|
||||||
void* pExtendedFeatures = null;
|
void* pExtendedFeatures = null;
|
||||||
|
@ -392,11 +390,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName))
|
if (physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName))
|
||||||
{
|
{
|
||||||
featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
TransformFeedback = supportedFeaturesTransformFeedback.TransformFeedback
|
TransformFeedback = supportedFeaturesTransformFeedback.TransformFeedback,
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresTransformFeedback;
|
pExtendedFeatures = &featuresTransformFeedback;
|
||||||
|
@ -406,12 +404,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
||||||
{
|
{
|
||||||
featuresPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT()
|
featuresPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
PrimitiveTopologyListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyListRestart,
|
PrimitiveTopologyListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyListRestart,
|
||||||
PrimitiveTopologyPatchListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyPatchListRestart
|
PrimitiveTopologyPatchListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyPatchListRestart,
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresPrimitiveTopologyListRestart;
|
pExtendedFeatures = &featuresPrimitiveTopologyListRestart;
|
||||||
|
@ -421,41 +419,41 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_robustness2"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_robustness2"))
|
||||||
{
|
{
|
||||||
featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
NullDescriptor = supportedFeaturesRobustness2.NullDescriptor
|
NullDescriptor = supportedFeaturesRobustness2.NullDescriptor,
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresRobustness2;
|
pExtendedFeatures = &featuresRobustness2;
|
||||||
}
|
}
|
||||||
|
|
||||||
var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT()
|
var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt,
|
SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
ExtendedDynamicState = physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName)
|
ExtendedDynamicState = physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName),
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresExtendedDynamicState;
|
pExtendedFeatures = &featuresExtendedDynamicState;
|
||||||
|
|
||||||
var featuresVk11 = new PhysicalDeviceVulkan11Features()
|
var featuresVk11 = new PhysicalDeviceVulkan11Features
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
ShaderDrawParameters = supportedFeaturesVk11.ShaderDrawParameters
|
ShaderDrawParameters = supportedFeaturesVk11.ShaderDrawParameters,
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresVk11;
|
pExtendedFeatures = &featuresVk11;
|
||||||
|
|
||||||
var featuresVk12 = new PhysicalDeviceVulkan12Features()
|
var featuresVk12 = new PhysicalDeviceVulkan12Features
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan12Features,
|
SType = StructureType.PhysicalDeviceVulkan12Features,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
DescriptorIndexing = physicalDevice.IsDeviceExtensionPresent("VK_EXT_descriptor_indexing"),
|
DescriptorIndexing = physicalDevice.IsDeviceExtensionPresent("VK_EXT_descriptor_indexing"),
|
||||||
DrawIndirectCount = physicalDevice.IsDeviceExtensionPresent(KhrDrawIndirectCount.ExtensionName),
|
DrawIndirectCount = physicalDevice.IsDeviceExtensionPresent(KhrDrawIndirectCount.ExtensionName),
|
||||||
UniformBufferStandardLayout = physicalDevice.IsDeviceExtensionPresent("VK_KHR_uniform_buffer_standard_layout")
|
UniformBufferStandardLayout = physicalDevice.IsDeviceExtensionPresent("VK_KHR_uniform_buffer_standard_layout"),
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresVk12;
|
pExtendedFeatures = &featuresVk12;
|
||||||
|
@ -464,11 +462,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_index_type_uint8"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_index_type_uint8"))
|
||||||
{
|
{
|
||||||
featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT()
|
featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt,
|
SType = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
IndexTypeUint8 = true
|
IndexTypeUint8 = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresIndexU8;
|
pExtendedFeatures = &featuresIndexU8;
|
||||||
|
@ -478,11 +476,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_fragment_shader_interlock"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_fragment_shader_interlock"))
|
||||||
{
|
{
|
||||||
featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT()
|
featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceFragmentShaderInterlockFeaturesExt,
|
SType = StructureType.PhysicalDeviceFragmentShaderInterlockFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
FragmentShaderPixelInterlock = true
|
FragmentShaderPixelInterlock = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresFragmentShaderInterlock;
|
pExtendedFeatures = &featuresFragmentShaderInterlock;
|
||||||
|
@ -492,11 +490,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_subgroup_size_control"))
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_subgroup_size_control"))
|
||||||
{
|
{
|
||||||
featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT()
|
featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceSubgroupSizeControlFeaturesExt,
|
SType = StructureType.PhysicalDeviceSubgroupSizeControlFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
SubgroupSizeControl = true
|
SubgroupSizeControl = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresSubgroupSizeControl;
|
pExtendedFeatures = &featuresSubgroupSizeControl;
|
||||||
|
@ -508,7 +506,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
supportedFeaturesCustomBorderColor.CustomBorderColors &&
|
supportedFeaturesCustomBorderColor.CustomBorderColors &&
|
||||||
supportedFeaturesCustomBorderColor.CustomBorderColorWithoutFormat)
|
supportedFeaturesCustomBorderColor.CustomBorderColorWithoutFormat)
|
||||||
{
|
{
|
||||||
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
|
@ -524,11 +522,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control") &&
|
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control") &&
|
||||||
supportedFeaturesDepthClipControl.DepthClipControl)
|
supportedFeaturesDepthClipControl.DepthClipControl)
|
||||||
{
|
{
|
||||||
featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
|
featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
DepthClipControl = true
|
DepthClipControl = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
pExtendedFeatures = &featuresDepthClipControl;
|
pExtendedFeatures = &featuresDepthClipControl;
|
||||||
|
@ -543,7 +541,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
|
ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var deviceCreateInfo = new DeviceCreateInfo()
|
var deviceCreateInfo = new DeviceCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.DeviceCreateInfo,
|
SType = StructureType.DeviceCreateInfo,
|
||||||
PNext = pExtendedFeatures,
|
PNext = pExtendedFeatures,
|
||||||
|
@ -551,7 +549,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PQueueCreateInfos = &queueCreateInfo,
|
PQueueCreateInfos = &queueCreateInfo,
|
||||||
PpEnabledExtensionNames = (byte**)ppEnabledExtensions,
|
PpEnabledExtensionNames = (byte**)ppEnabledExtensions,
|
||||||
EnabledExtensionCount = (uint)enabledExtensions.Length,
|
EnabledExtensionCount = (uint)enabledExtensions.Length,
|
||||||
PEnabledFeatures = &features
|
PEnabledFeatures = &features,
|
||||||
};
|
};
|
||||||
|
|
||||||
api.CreateDevice(physicalDevice.PhysicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();
|
api.CreateDevice(physicalDevice.PhysicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();
|
||||||
|
|
|
@ -11,6 +11,9 @@ 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 Format = Ryujinx.Graphics.GAL.Format;
|
||||||
|
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
||||||
|
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -143,14 +146,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
BackgroundQueueLock = new object();
|
BackgroundQueueLock = new object();
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceProperties2 properties2 = new PhysicalDeviceProperties2()
|
PhysicalDeviceProperties2 properties2 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceProperties2
|
SType = StructureType.PhysicalDeviceProperties2,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceBlendOperationAdvancedPropertiesEXT propertiesBlendOperationAdvanced = new PhysicalDeviceBlendOperationAdvancedPropertiesEXT()
|
PhysicalDeviceBlendOperationAdvancedPropertiesEXT propertiesBlendOperationAdvanced = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceBlendOperationAdvancedPropertiesExt
|
SType = StructureType.PhysicalDeviceBlendOperationAdvancedPropertiesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool supportsBlendOperationAdvanced = _physicalDevice.IsDeviceExtensionPresent("VK_EXT_blend_operation_advanced");
|
bool supportsBlendOperationAdvanced = _physicalDevice.IsDeviceExtensionPresent("VK_EXT_blend_operation_advanced");
|
||||||
|
@ -161,9 +164,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
properties2.PNext = &propertiesBlendOperationAdvanced;
|
properties2.PNext = &propertiesBlendOperationAdvanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDeviceSubgroupSizeControlPropertiesEXT propertiesSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlPropertiesEXT()
|
PhysicalDeviceSubgroupSizeControlPropertiesEXT propertiesSubgroupSizeControl = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceSubgroupSizeControlPropertiesExt
|
SType = StructureType.PhysicalDeviceSubgroupSizeControlPropertiesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool supportsSubgroupSizeControl = _physicalDevice.IsDeviceExtensionPresent("VK_EXT_subgroup_size_control");
|
bool supportsSubgroupSizeControl = _physicalDevice.IsDeviceExtensionPresent("VK_EXT_subgroup_size_control");
|
||||||
|
@ -175,9 +178,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
bool supportsTransformFeedback = _physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName);
|
bool supportsTransformFeedback = _physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName);
|
||||||
|
|
||||||
PhysicalDeviceTransformFeedbackPropertiesEXT propertiesTransformFeedback = new PhysicalDeviceTransformFeedbackPropertiesEXT()
|
PhysicalDeviceTransformFeedbackPropertiesEXT propertiesTransformFeedback = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceTransformFeedbackPropertiesExt
|
SType = StructureType.PhysicalDeviceTransformFeedbackPropertiesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (supportsTransformFeedback)
|
if (supportsTransformFeedback)
|
||||||
|
@ -186,44 +189,44 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
properties2.PNext = &propertiesTransformFeedback;
|
properties2.PNext = &propertiesTransformFeedback;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalDevicePortabilitySubsetPropertiesKHR propertiesPortabilitySubset = new PhysicalDevicePortabilitySubsetPropertiesKHR()
|
PhysicalDevicePortabilitySubsetPropertiesKHR propertiesPortabilitySubset = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDevicePortabilitySubsetPropertiesKhr
|
SType = StructureType.PhysicalDevicePortabilitySubsetPropertiesKhr,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceFeatures2 features2 = new PhysicalDeviceFeatures2()
|
PhysicalDeviceFeatures2 features2 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceFeatures2
|
SType = StructureType.PhysicalDeviceFeatures2,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT featuresPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT()
|
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT featuresPrimitiveTopologyListRestart = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt
|
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceRobustness2FeaturesEXT featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
PhysicalDeviceRobustness2FeaturesEXT featuresRobustness2 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt
|
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceShaderFloat16Int8FeaturesKHR featuresShaderInt8 = new PhysicalDeviceShaderFloat16Int8FeaturesKHR()
|
PhysicalDeviceShaderFloat16Int8FeaturesKHR featuresShaderInt8 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceShaderFloat16Int8Features
|
SType = StructureType.PhysicalDeviceShaderFloat16Int8Features,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
PhysicalDeviceCustomBorderColorFeaturesEXT featuresCustomBorderColor = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt
|
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceDepthClipControlFeaturesEXT featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
|
PhysicalDeviceDepthClipControlFeaturesEXT featuresDepthClipControl = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt
|
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDevicePortabilitySubsetFeaturesKHR featuresPortabilitySubset = new PhysicalDevicePortabilitySubsetFeaturesKHR()
|
PhysicalDevicePortabilitySubsetFeaturesKHR featuresPortabilitySubset = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDevicePortabilitySubsetFeaturesKhr
|
SType = StructureType.PhysicalDevicePortabilitySubsetFeaturesKhr,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
if (_physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
||||||
|
@ -359,7 +362,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_counters = new Counters(this, _device, _pipeline);
|
_counters = new Counters(this, _device, _pipeline);
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void SetupContext(GraphicsDebugLevel logLevel)
|
private void SetupContext(GraphicsDebugLevel logLevel)
|
||||||
{
|
{
|
||||||
_instance = VulkanInitialization.CreateInstance(Api, logLevel, _getRequiredExtensions());
|
_instance = VulkanInitialization.CreateInstance(Api, logLevel, _getRequiredExtensions());
|
||||||
_debugMessenger = new VulkanDebugMessenger(Api, _instance.Instance, logLevel);
|
_debugMessenger = new VulkanDebugMessenger(Api, _instance.Instance, logLevel);
|
||||||
|
@ -415,18 +418,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
return new ShaderCollection(this, _device, sources, info.ResourceLayout, info.State ?? default, info.FromCache);
|
return new ShaderCollection(this, _device, sources, info.ResourceLayout, info.State ?? default, info.FromCache);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return new ShaderCollection(this, _device, sources, info.ResourceLayout);
|
return new ShaderCollection(this, _device, sources, info.ResourceLayout);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
internal ShaderCollection CreateProgramWithMinimalLayout(ShaderSource[] sources, ResourceLayout resourceLayout, SpecDescription[] specDescription = null)
|
internal ShaderCollection CreateProgramWithMinimalLayout(ShaderSource[] sources, ResourceLayout resourceLayout, SpecDescription[] specDescription = null)
|
||||||
{
|
{
|
||||||
return new ShaderCollection(this, _device, sources, resourceLayout, specDescription, isMinimal: true);
|
return new ShaderCollection(this, _device, sources, resourceLayout, specDescription, isMinimal: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISampler CreateSampler(GAL.SamplerCreateInfo info)
|
public ISampler CreateSampler(SamplerCreateInfo info)
|
||||||
{
|
{
|
||||||
return new SamplerHolder(this, _device, info);
|
return new SamplerHolder(this, _device, info);
|
||||||
}
|
}
|
||||||
|
@ -483,83 +484,83 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
FormatFeatureFlags.TransferDstBit;
|
FormatFeatureFlags.TransferDstBit;
|
||||||
|
|
||||||
bool supportsBc123CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
bool supportsBc123CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
GAL.Format.Bc1RgbaSrgb,
|
Format.Bc1RgbaSrgb,
|
||||||
GAL.Format.Bc1RgbaUnorm,
|
Format.Bc1RgbaUnorm,
|
||||||
GAL.Format.Bc2Srgb,
|
Format.Bc2Srgb,
|
||||||
GAL.Format.Bc2Unorm,
|
Format.Bc2Unorm,
|
||||||
GAL.Format.Bc3Srgb,
|
Format.Bc3Srgb,
|
||||||
GAL.Format.Bc3Unorm);
|
Format.Bc3Unorm);
|
||||||
|
|
||||||
bool supportsBc45CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
bool supportsBc45CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
GAL.Format.Bc4Snorm,
|
Format.Bc4Snorm,
|
||||||
GAL.Format.Bc4Unorm,
|
Format.Bc4Unorm,
|
||||||
GAL.Format.Bc5Snorm,
|
Format.Bc5Snorm,
|
||||||
GAL.Format.Bc5Unorm);
|
Format.Bc5Unorm);
|
||||||
|
|
||||||
bool supportsBc67CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
bool supportsBc67CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
GAL.Format.Bc6HSfloat,
|
Format.Bc6HSfloat,
|
||||||
GAL.Format.Bc6HUfloat,
|
Format.Bc6HUfloat,
|
||||||
GAL.Format.Bc7Srgb,
|
Format.Bc7Srgb,
|
||||||
GAL.Format.Bc7Unorm);
|
Format.Bc7Unorm);
|
||||||
|
|
||||||
bool supportsEtc2CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
bool supportsEtc2CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
GAL.Format.Etc2RgbaSrgb,
|
Format.Etc2RgbaSrgb,
|
||||||
GAL.Format.Etc2RgbaUnorm,
|
Format.Etc2RgbaUnorm,
|
||||||
GAL.Format.Etc2RgbPtaSrgb,
|
Format.Etc2RgbPtaSrgb,
|
||||||
GAL.Format.Etc2RgbPtaUnorm,
|
Format.Etc2RgbPtaUnorm,
|
||||||
GAL.Format.Etc2RgbSrgb,
|
Format.Etc2RgbSrgb,
|
||||||
GAL.Format.Etc2RgbUnorm);
|
Format.Etc2RgbUnorm);
|
||||||
|
|
||||||
bool supports5BitComponentFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
bool supports5BitComponentFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
GAL.Format.R5G6B5Unorm,
|
Format.R5G6B5Unorm,
|
||||||
GAL.Format.R5G5B5A1Unorm,
|
Format.R5G5B5A1Unorm,
|
||||||
GAL.Format.R5G5B5X1Unorm,
|
Format.R5G5B5X1Unorm,
|
||||||
GAL.Format.B5G6R5Unorm,
|
Format.B5G6R5Unorm,
|
||||||
GAL.Format.B5G5R5A1Unorm,
|
Format.B5G5R5A1Unorm,
|
||||||
GAL.Format.A1B5G5R5Unorm);
|
Format.A1B5G5R5Unorm);
|
||||||
|
|
||||||
bool supportsR4G4B4A4Format = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
bool supportsR4G4B4A4Format = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
GAL.Format.R4G4B4A4Unorm);
|
Format.R4G4B4A4Unorm);
|
||||||
|
|
||||||
bool supportsAstcFormats = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
bool supportsAstcFormats = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||||
GAL.Format.Astc4x4Unorm,
|
Format.Astc4x4Unorm,
|
||||||
GAL.Format.Astc5x4Unorm,
|
Format.Astc5x4Unorm,
|
||||||
GAL.Format.Astc5x5Unorm,
|
Format.Astc5x5Unorm,
|
||||||
GAL.Format.Astc6x5Unorm,
|
Format.Astc6x5Unorm,
|
||||||
GAL.Format.Astc6x6Unorm,
|
Format.Astc6x6Unorm,
|
||||||
GAL.Format.Astc8x5Unorm,
|
Format.Astc8x5Unorm,
|
||||||
GAL.Format.Astc8x6Unorm,
|
Format.Astc8x6Unorm,
|
||||||
GAL.Format.Astc8x8Unorm,
|
Format.Astc8x8Unorm,
|
||||||
GAL.Format.Astc10x5Unorm,
|
Format.Astc10x5Unorm,
|
||||||
GAL.Format.Astc10x6Unorm,
|
Format.Astc10x6Unorm,
|
||||||
GAL.Format.Astc10x8Unorm,
|
Format.Astc10x8Unorm,
|
||||||
GAL.Format.Astc10x10Unorm,
|
Format.Astc10x10Unorm,
|
||||||
GAL.Format.Astc12x10Unorm,
|
Format.Astc12x10Unorm,
|
||||||
GAL.Format.Astc12x12Unorm,
|
Format.Astc12x12Unorm,
|
||||||
GAL.Format.Astc4x4Srgb,
|
Format.Astc4x4Srgb,
|
||||||
GAL.Format.Astc5x4Srgb,
|
Format.Astc5x4Srgb,
|
||||||
GAL.Format.Astc5x5Srgb,
|
Format.Astc5x5Srgb,
|
||||||
GAL.Format.Astc6x5Srgb,
|
Format.Astc6x5Srgb,
|
||||||
GAL.Format.Astc6x6Srgb,
|
Format.Astc6x6Srgb,
|
||||||
GAL.Format.Astc8x5Srgb,
|
Format.Astc8x5Srgb,
|
||||||
GAL.Format.Astc8x6Srgb,
|
Format.Astc8x6Srgb,
|
||||||
GAL.Format.Astc8x8Srgb,
|
Format.Astc8x8Srgb,
|
||||||
GAL.Format.Astc10x5Srgb,
|
Format.Astc10x5Srgb,
|
||||||
GAL.Format.Astc10x6Srgb,
|
Format.Astc10x6Srgb,
|
||||||
GAL.Format.Astc10x8Srgb,
|
Format.Astc10x8Srgb,
|
||||||
GAL.Format.Astc10x10Srgb,
|
Format.Astc10x10Srgb,
|
||||||
GAL.Format.Astc12x10Srgb,
|
Format.Astc12x10Srgb,
|
||||||
GAL.Format.Astc12x12Srgb);
|
Format.Astc12x12Srgb);
|
||||||
|
|
||||||
PhysicalDeviceVulkan12Features featuresVk12 = new PhysicalDeviceVulkan12Features()
|
PhysicalDeviceVulkan12Features featuresVk12 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceVulkan12Features
|
SType = StructureType.PhysicalDeviceVulkan12Features,
|
||||||
};
|
};
|
||||||
|
|
||||||
PhysicalDeviceFeatures2 features2 = new PhysicalDeviceFeatures2()
|
PhysicalDeviceFeatures2 features2 = new()
|
||||||
{
|
{
|
||||||
SType = StructureType.PhysicalDeviceFeatures2,
|
SType = StructureType.PhysicalDeviceFeatures2,
|
||||||
PNext = &featuresVk12
|
PNext = &featuresVk12,
|
||||||
};
|
};
|
||||||
|
|
||||||
Api.GetPhysicalDeviceFeatures2(_physicalDevice.PhysicalDevice, &features2);
|
Api.GetPhysicalDeviceFeatures2(_physicalDevice.PhysicalDevice, &features2);
|
||||||
|
@ -665,11 +666,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
return $"{(driverVersionRaw >> 22) & 0x3FF}.{(driverVersionRaw >> 14) & 0xFF}.{(driverVersionRaw >> 6) & 0xFF}.{driverVersionRaw & 0x3F}";
|
return $"{(driverVersionRaw >> 22) & 0x3FF}.{(driverVersionRaw >> 14) & 0xFF}.{(driverVersionRaw >> 6) & 0xFF}.{driverVersionRaw & 0x3F}";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return ParseStandardVulkanVersion(driverVersionRaw);
|
return ParseStandardVulkanVersion(driverVersionRaw);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private unsafe void PrintGpuInformation()
|
private unsafe void PrintGpuInformation()
|
||||||
{
|
{
|
||||||
|
@ -696,24 +695,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal GAL.PrimitiveTopology TopologyRemap(GAL.PrimitiveTopology topology)
|
internal PrimitiveTopology TopologyRemap(PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
return topology switch
|
return topology switch
|
||||||
{
|
{
|
||||||
GAL.PrimitiveTopology.Quads => GAL.PrimitiveTopology.Triangles,
|
PrimitiveTopology.Quads => PrimitiveTopology.Triangles,
|
||||||
GAL.PrimitiveTopology.QuadStrip => GAL.PrimitiveTopology.TriangleStrip,
|
PrimitiveTopology.QuadStrip => PrimitiveTopology.TriangleStrip,
|
||||||
GAL.PrimitiveTopology.TriangleFan => Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.NoTriangleFans) ? GAL.PrimitiveTopology.Triangles : topology,
|
PrimitiveTopology.TriangleFan => Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.NoTriangleFans) ? PrimitiveTopology.Triangles : topology,
|
||||||
_ => topology
|
_ => topology,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool TopologyUnsupported(GAL.PrimitiveTopology topology)
|
internal bool TopologyUnsupported(PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
return topology switch
|
return topology switch
|
||||||
{
|
{
|
||||||
GAL.PrimitiveTopology.Quads => true,
|
PrimitiveTopology.Quads => true,
|
||||||
GAL.PrimitiveTopology.TriangleFan => Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.NoTriangleFans),
|
PrimitiveTopology.TriangleFan => Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.NoTriangleFans),
|
||||||
_ => false
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
CreateSwapchain();
|
CreateSwapchain();
|
||||||
|
|
||||||
var semaphoreCreateInfo = new SemaphoreCreateInfo()
|
var semaphoreCreateInfo = new SemaphoreCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.SemaphoreCreateInfo
|
SType = StructureType.SemaphoreCreateInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _imageAvailableSemaphore).ThrowOnError();
|
gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _imageAvailableSemaphore).ThrowOnError();
|
||||||
|
@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var oldSwapchain = _swapchain;
|
var oldSwapchain = _swapchain;
|
||||||
|
|
||||||
var swapchainCreateInfo = new SwapchainCreateInfoKHR()
|
var swapchainCreateInfo = new SwapchainCreateInfoKHR
|
||||||
{
|
{
|
||||||
SType = StructureType.SwapchainCreateInfoKhr,
|
SType = StructureType.SwapchainCreateInfoKhr,
|
||||||
Surface = _surface,
|
Surface = _surface,
|
||||||
|
@ -130,7 +130,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
PreTransform = capabilities.CurrentTransform,
|
PreTransform = capabilities.CurrentTransform,
|
||||||
CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
|
CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
|
||||||
PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
|
PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
|
||||||
Clipped = true
|
Clipped = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.SwapchainApi.CreateSwapchain(_device, swapchainCreateInfo, null, out _swapchain).ThrowOnError();
|
_gd.SwapchainApi.CreateSwapchain(_device, swapchainCreateInfo, null, out _swapchain).ThrowOnError();
|
||||||
|
@ -164,14 +164,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, 1, 0, 1);
|
var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, 1, 0, 1);
|
||||||
|
|
||||||
var imageCreateInfo = new ImageViewCreateInfo()
|
var imageCreateInfo = new ImageViewCreateInfo
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageViewCreateInfo,
|
SType = StructureType.ImageViewCreateInfo,
|
||||||
Image = swapchainImage,
|
Image = swapchainImage,
|
||||||
ViewType = ImageViewType.Type2D,
|
ViewType = ImageViewType.Type2D,
|
||||||
Format = format,
|
Format = format,
|
||||||
Components = componentMapping,
|
Components = componentMapping,
|
||||||
SubresourceRange = subresourceRange
|
SubresourceRange = subresourceRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.Api.CreateImageView(_device, imageCreateInfo, null, out var imageView).ThrowOnError();
|
_gd.Api.CreateImageView(_device, imageCreateInfo, null, out var imageView).ThrowOnError();
|
||||||
|
@ -234,14 +234,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
return capabilities.CurrentExtent;
|
return capabilities.CurrentExtent;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
uint width = Math.Max(capabilities.MinImageExtent.Width, Math.Min(capabilities.MaxImageExtent.Width, SurfaceWidth));
|
uint width = Math.Max(capabilities.MinImageExtent.Width, Math.Min(capabilities.MaxImageExtent.Width, SurfaceWidth));
|
||||||
uint height = Math.Max(capabilities.MinImageExtent.Height, Math.Min(capabilities.MaxImageExtent.Height, SurfaceHeight));
|
uint height = Math.Max(capabilities.MinImageExtent.Height, Math.Min(capabilities.MaxImageExtent.Height, SurfaceHeight));
|
||||||
|
|
||||||
return new Extent2D(width, height);
|
return new Extent2D(width, height);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe override void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
public unsafe override void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||||
{
|
{
|
||||||
|
@ -413,7 +411,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
Result result;
|
Result result;
|
||||||
|
|
||||||
var presentInfo = new PresentInfoKHR()
|
var presentInfo = new PresentInfoKHR
|
||||||
{
|
{
|
||||||
SType = StructureType.PresentInfoKhr,
|
SType = StructureType.PresentInfoKhr,
|
||||||
WaitSemaphoreCount = 1,
|
WaitSemaphoreCount = 1,
|
||||||
|
@ -421,7 +419,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SwapchainCount = 1,
|
SwapchainCount = 1,
|
||||||
PSwapchains = &swapchain,
|
PSwapchains = &swapchain,
|
||||||
PImageIndices = &nextImage,
|
PImageIndices = &nextImage,
|
||||||
PResults = &result
|
PResults = &result,
|
||||||
};
|
};
|
||||||
|
|
||||||
lock (_gd.QueueLock)
|
lock (_gd.QueueLock)
|
||||||
|
@ -529,7 +527,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ColorBit, 0, 1, 0, 1);
|
var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ColorBit, 0, 1, 0, 1);
|
||||||
|
|
||||||
var barrier = new ImageMemoryBarrier()
|
var barrier = new ImageMemoryBarrier
|
||||||
{
|
{
|
||||||
SType = StructureType.ImageMemoryBarrier,
|
SType = StructureType.ImageMemoryBarrier,
|
||||||
SrcAccessMask = srcAccess,
|
SrcAccessMask = srcAccess,
|
||||||
|
@ -539,7 +537,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
Image = image,
|
Image = image,
|
||||||
SubresourceRange = subresourceRange
|
SubresourceRange = subresourceRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
_gd.Api.CmdPipelineBarrier(
|
_gd.Api.CmdPipelineBarrier(
|
||||||
|
|
Loading…
Reference in a new issue