[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:
TSRBerry 2023-07-01 12:31:42 +02:00 committed by GitHub
parent 12c5f6ee89
commit 801b71a128
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1134 additions and 1230 deletions

View file

@ -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})");

View file

@ -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();

View file

@ -131,7 +131,7 @@
public void Clear(int bit) public void Clear(int bit)
{ {
int wordIndex = bit >> IntShift; int wordIndex = bit >> IntShift;
int wordBit = bit & IntMask; int wordBit = bit & IntMask;
long wordMask = 1L << wordBit; long wordMask = 1L << wordBit;

View file

@ -7,6 +7,6 @@
HostMappedNoCache, HostMappedNoCache,
HostMapped, HostMapped,
DeviceLocal, DeviceLocal,
DeviceLocalMapped DeviceLocalMapped,
} }
} }

View file

@ -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,17 +181,13 @@ namespace Ryujinx.Graphics.Vulkan
return true; return true;
} }
else
{
return false;
}
}
else
{
_swapQueued = false;
return true; return false;
} }
_swapQueued = false;
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,26 +440,24 @@ namespace Ryujinx.Graphics.Vulkan
return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount); return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount);
} }
BackgroundResource resource = _gd.BackgroundResources.Get();
if (_gd.CommandBufferPool.OwnedByCurrentThread)
{
_gd.FlushAllCommands();
result = resource.GetFlushBuffer().GetBufferData(_gd.CommandBufferPool, this, offset, size);
}
else else
{ {
BackgroundResource resource = _gd.BackgroundResources.Get(); result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
if (_gd.CommandBufferPool.OwnedByCurrentThread)
{
_gd.FlushAllCommands();
result = resource.GetFlushBuffer().GetBufferData(_gd.CommandBufferPool, this, offset, size);
}
else
{
result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
}
_flushLock.ReleaseReaderLock();
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
return PinnedSpan<byte>.UnsafeFromSpan(result);
} }
_flushLock.ReleaseReaderLock();
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
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(

View file

@ -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,

View file

@ -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();
} }

View file

@ -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)
{ {

View file

@ -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);

View file

@ -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)

View file

@ -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;
} }

View file

@ -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);
} }
} }
@ -186,15 +187,13 @@ namespace Ryujinx.Graphics.Vulkan
{ {
if (disposing) if (disposing)
{ {
unsafe _currentPool?.Dispose();
{
_currentPool?.Dispose();
}
} }
} }
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
Dispose(true); Dispose(true);
} }
} }

View file

@ -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++)
{ {

View file

@ -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;

View file

@ -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,14 +138,14 @@ 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);
var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize); var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize);
_renderer.BufferManager.SetData(bufferHandle, 0, dimensionsBuffer); _renderer.BufferManager.SetData(bufferHandle, 0, dimensionsBuffer);
ReadOnlySpan<float> sharpeningBuffer = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f)}; ReadOnlySpan<float> sharpeningBuffer = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f) };
var sharpeningBufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, sizeof(float)); var sharpeningBufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, sizeof(float));
_renderer.BufferManager.SetData(sharpeningBufferHandle, 0, sharpeningBuffer); _renderer.BufferManager.SetData(sharpeningBufferHandle, 0, sharpeningBuffer);

View file

@ -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);
} }

View file

@ -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,

View file

@ -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,
}; };
} }

View file

@ -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);

View file

@ -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;
} }
} }
} }

View file

@ -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;
} }
} }
} }

View file

@ -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();

View file

@ -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

View file

@ -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();

View file

@ -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,55 +1460,55 @@ 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(
@ -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();

View file

@ -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);

View file

@ -85,11 +85,9 @@ 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)
{ {

View file

@ -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;

View file

@ -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;
} }

View file

@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly HostMemoryAllocator _hostMemory; private readonly HostMemoryAllocator _hostMemory;
public DeviceMemory Memory { get; } public DeviceMemory Memory { get; }
public IntPtr HostPointer { get;} public IntPtr HostPointer { get; }
public ulong Offset { get; } public ulong Offset { get; }
public ulong Size { get; } public ulong Size { get; }

View file

@ -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(

View file

@ -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();
@ -213,12 +213,9 @@ namespace Ryujinx.Graphics.Vulkan
if (map) if (map)
{ {
unsafe void* pointer = null;
{ _api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError();
void* pointer = null; hostPointer = (IntPtr)pointer;
_api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError();
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++)
{ {

View file

@ -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)]

View file

@ -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++)

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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();
} }

View file

@ -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)
{ {

View file

@ -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();

View file

@ -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();

View file

@ -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()

View file

@ -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)
{ {

View file

@ -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,10 +116,8 @@ 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);
}
} }
} }

View file

@ -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();

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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,
}; };
} }

View file

@ -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)
{ {

View file

@ -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,

View file

@ -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()

View file

@ -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)
{ {

View file

@ -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;
} }

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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,8 +352,9 @@ namespace Ryujinx.Graphics.Vulkan
return; return;
} }
else if (_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitSrcBit, srcFormat) &&
_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitDstBit, dstFormat)) if (_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitSrcBit, srcFormat) &&
_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitDstBit, dstFormat))
{ {
TextureCopy.Blit( TextureCopy.Blit(
_gd.Api, _gd.Api,
@ -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,10 +542,8 @@ 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,10 +556,8 @@ 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;

View file

@ -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}",
}; };
} }
} }

View file

@ -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,17 +74,15 @@ namespace Ryujinx.Graphics.Vulkan
return; return;
} }
else
autoBuffer = gd.BufferManager.GetBuffer(cbs.CommandBuffer, _handle, false, out int size);
// The original stride must be reapplied in case it was rewritten.
state.Internal.VertexBindingDescriptions[DescriptorIndex].Stride = (uint)_stride;
if (_offset >= size)
{ {
autoBuffer = gd.BufferManager.GetBuffer(cbs.CommandBuffer, _handle, false, out int size); autoBuffer = null;
// The original stride must be reapplied in case it was rewritten.
state.Internal.VertexBindingDescriptions[DescriptorIndex].Stride = (uint)_stride;
if (_offset >= size)
{
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.

View file

@ -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)
{ {

View file

@ -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

View file

@ -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();

View file

@ -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,10 +418,8 @@ 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)
@ -426,7 +427,7 @@ namespace Ryujinx.Graphics.Vulkan
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,10 +666,8 @@ 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,
}; };
} }

View file

@ -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,13 +234,11 @@ 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 height = Math.Max(capabilities.MinImageExtent.Height, Math.Min(capabilities.MaxImageExtent.Height, SurfaceHeight));
return new Extent2D(width, height); 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));
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)
@ -350,10 +348,10 @@ namespace Ryujinx.Graphics.Vulkan
float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY)); float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY));
float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX)); float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX));
int dstWidth = (int)(_width * ratioX); int dstWidth = (int)(_width * ratioX);
int dstHeight = (int)(_height * ratioY); int dstHeight = (int)(_height * ratioY);
int dstPaddingX = (_width - dstWidth) / 2; int dstPaddingX = (_width - dstWidth) / 2;
int dstPaddingY = (_height - dstHeight) / 2; int dstPaddingY = (_height - dstHeight) / 2;
int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX; int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX;
@ -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(

View file

@ -3,7 +3,7 @@ using System;
namespace Ryujinx.Graphics.Vulkan namespace Ryujinx.Graphics.Vulkan
{ {
internal abstract class WindowBase: IWindow internal abstract class WindowBase : IWindow
{ {
public bool ScreenCaptureRequested { get; set; } public bool ScreenCaptureRequested { get; set; }