mirror of
https://github.com/GreemDev/Ryujinx.git
synced 2024-11-28 03:40:50 +01:00
[Ryujinx.Graphics.Vulkan] Address dotnet-format issues (#5378)
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0059 warnings * Address dotnet format CA1816 warnings * Fix new dotnet-format issues after rebase * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Format if-blocks correctly * Another rebase, another dotnet format run * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format analyzers after rebase * Run dotnet format style after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Run dotnet format after rebase * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Fix naming rule violations * Remove redundant code * Rename generics * Address review feedback * Remove SetOrigin
This commit is contained in:
parent
12c5f6ee89
commit
801b71a128
@ -8,16 +8,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
internal class AutoFlushCounter
|
||||
{
|
||||
// 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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
private const int SyncWaitAverageCount = 20;
|
||||
@ -34,11 +34,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private int _consecutiveQueries;
|
||||
private int _queryCount;
|
||||
|
||||
private int[] _queryCountHistory = new int[3];
|
||||
private readonly int[] _queryCountHistory = new int[3];
|
||||
private int _queryCountHistoryIndex;
|
||||
private int _remainingQueries;
|
||||
|
||||
private long[] _syncWaitHistory = new long[SyncWaitAverageCount];
|
||||
private readonly long[] _syncWaitHistory = new long[SyncWaitAverageCount];
|
||||
private int _syncWaitHistoryIndex;
|
||||
|
||||
private bool _fastFlushMode;
|
||||
@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return false;
|
||||
}
|
||||
|
||||
long flushTimeout = DrawFlushTimer;
|
||||
long flushTimeout = _drawFlushTimer;
|
||||
|
||||
long now = Stopwatch.GetTimestamp();
|
||||
|
||||
@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return false;
|
||||
}
|
||||
|
||||
long flushTimeout = FramebufferFlushTimer;
|
||||
long flushTimeout = _framebufferFlushTimer;
|
||||
|
||||
long now = Stopwatch.GetTimestamp();
|
||||
|
||||
@ -169,7 +169,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
long averageWait = (long)_syncWaitHistory.Average();
|
||||
|
||||
if (_fastFlushMode ? averageWait < FastFlushExitThreshold : averageWait > FastFlushEnterThreshold)
|
||||
if (_fastFlushMode ? averageWait < _fastFlushExitThreshold : averageWait > _fastFlushEnterThreshold)
|
||||
{
|
||||
_fastFlushMode = !_fastFlushMode;
|
||||
Logger.Debug?.PrintMsg(LogClass.Gpu, $"Switched fast flush mode: ({_fastFlushMode})");
|
||||
|
@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
class BackgroundResource : IDisposable
|
||||
{
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
private Device _device;
|
||||
|
||||
private CommandBufferPool _pool;
|
||||
@ -38,10 +38,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public PersistentFlushBuffer GetFlushBuffer()
|
||||
{
|
||||
if (_flushBuffer == null)
|
||||
{
|
||||
_flushBuffer = new PersistentFlushBuffer(_gd);
|
||||
}
|
||||
_flushBuffer ??= new PersistentFlushBuffer(_gd);
|
||||
|
||||
return _flushBuffer;
|
||||
}
|
||||
@ -55,10 +52,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
class BackgroundResources : IDisposable
|
||||
{
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
private Device _device;
|
||||
|
||||
private Dictionary<Thread, BackgroundResource> _resources;
|
||||
private readonly Dictionary<Thread, BackgroundResource> _resources;
|
||||
|
||||
public BackgroundResources(VulkanRenderer gd, Device device)
|
||||
{
|
||||
@ -89,8 +86,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
lock (_resources)
|
||||
{
|
||||
BackgroundResource resource;
|
||||
if (!_resources.TryGetValue(thread, out resource))
|
||||
if (!_resources.TryGetValue(thread, out BackgroundResource resource))
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
|
@ -131,7 +131,7 @@
|
||||
public void Clear(int bit)
|
||||
{
|
||||
int wordIndex = bit >> IntShift;
|
||||
int wordBit = bit & IntMask;
|
||||
int wordBit = bit & IntMask;
|
||||
|
||||
long wordMask = 1L << wordBit;
|
||||
|
||||
@ -154,4 +154,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,6 @@
|
||||
HostMappedNoCache,
|
||||
HostMapped,
|
||||
DeviceLocal,
|
||||
DeviceLocalMapped
|
||||
DeviceLocalMapped,
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private MemoryAllocation _allocation;
|
||||
private Auto<DisposableBuffer> _buffer;
|
||||
private Auto<MemoryAllocation> _allocationAuto;
|
||||
private bool _allocationImported;
|
||||
private readonly bool _allocationImported;
|
||||
private ulong _bufferHandle;
|
||||
|
||||
private CacheByRange<BufferHolder> _cachedConvertedBuffers;
|
||||
@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private bool _lastAccessIsWrite;
|
||||
|
||||
private BufferAllocationType _baseType;
|
||||
private readonly BufferAllocationType _baseType;
|
||||
private BufferAllocationType _currentType;
|
||||
private bool _swapQueued;
|
||||
|
||||
@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private int _flushTemp;
|
||||
private int _lastFlushWrite = -1;
|
||||
|
||||
private ReaderWriterLock _flushLock;
|
||||
private readonly ReaderWriterLock _flushLock;
|
||||
private FenceHolder _flushFence;
|
||||
private int _flushWaiting;
|
||||
|
||||
@ -143,10 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cbs == null)
|
||||
{
|
||||
cbs = _gd.CommandBufferPool.Rent();
|
||||
}
|
||||
cbs ??= _gd.CommandBufferPool.Rent();
|
||||
|
||||
CommandBufferScoped cbsV = cbs.Value;
|
||||
|
||||
@ -184,17 +181,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_swapQueued = false;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
_swapQueued = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ConsiderBackingSwap()
|
||||
@ -251,13 +244,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public unsafe Auto<DisposableBufferView> CreateView(VkFormat format, int offset, int size, Action invalidateView)
|
||||
{
|
||||
var bufferViewCreateInfo = new BufferViewCreateInfo()
|
||||
var bufferViewCreateInfo = new BufferViewCreateInfo
|
||||
{
|
||||
SType = StructureType.BufferViewCreateInfo,
|
||||
Buffer = new VkBuffer(_bufferHandle),
|
||||
Format = format,
|
||||
Offset = (uint)offset,
|
||||
Range = (uint)size
|
||||
Range = (uint)size,
|
||||
};
|
||||
|
||||
_gd.Api.CreateBufferView(_device, bufferViewCreateInfo, null, out var bufferView).ThrowOnError();
|
||||
@ -288,11 +281,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (needsBarrier)
|
||||
{
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = DefaultAccessFlags,
|
||||
DstAccessMask = DefaultAccessFlags
|
||||
DstAccessMask = DefaultAccessFlags,
|
||||
};
|
||||
|
||||
_gd.Api.CmdPipelineBarrier(
|
||||
@ -366,14 +359,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return Unsafe.As<ulong, BufferHandle>(ref handle);
|
||||
}
|
||||
|
||||
public unsafe IntPtr Map(int offset, int mappingSize)
|
||||
public IntPtr Map(int offset, int mappingSize)
|
||||
{
|
||||
return _map;
|
||||
}
|
||||
|
||||
private void ClearFlushFence()
|
||||
{
|
||||
// Asusmes _flushLock is held as writer.
|
||||
// Assumes _flushLock is held as writer.
|
||||
|
||||
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);
|
||||
|
||||
@ -447,26 +440,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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
|
||||
{
|
||||
BackgroundResource resource = _gd.BackgroundResources.Get();
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
public unsafe Span<byte> GetDataStorage(int offset, int size)
|
||||
@ -503,7 +494,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
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);
|
||||
|
||||
@ -542,7 +533,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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
|
||||
{
|
||||
@ -657,7 +648,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int offset,
|
||||
int size)
|
||||
{
|
||||
BufferMemoryBarrier memoryBarrier = new BufferMemoryBarrier()
|
||||
BufferMemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.BufferMemoryBarrier,
|
||||
SrcAccessMask = srcAccessMask,
|
||||
@ -666,7 +657,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
Buffer = buffer,
|
||||
Offset = (ulong)offset,
|
||||
Size = (ulong)size
|
||||
Size = (ulong)size,
|
||||
};
|
||||
|
||||
gd.Api.CmdPipelineBarrier(
|
||||
|
@ -73,12 +73,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||
}
|
||||
|
||||
var bufferCreateInfo = new BufferCreateInfo()
|
||||
var bufferCreateInfo = new BufferCreateInfo
|
||||
{
|
||||
SType = StructureType.BufferCreateInfo,
|
||||
Size = (ulong)size,
|
||||
Usage = usage,
|
||||
SharingMode = SharingMode.Exclusive
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
};
|
||||
|
||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
||||
@ -134,12 +134,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||
}
|
||||
|
||||
var bufferCreateInfo = new BufferCreateInfo()
|
||||
var bufferCreateInfo = new BufferCreateInfo
|
||||
{
|
||||
SType = StructureType.BufferCreateInfo,
|
||||
Size = (ulong)Environment.SystemPageSize,
|
||||
Usage = usage,
|
||||
SharingMode = SharingMode.Exclusive
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
};
|
||||
|
||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
||||
@ -169,12 +169,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||
}
|
||||
|
||||
var bufferCreateInfo = new BufferCreateInfo()
|
||||
var bufferCreateInfo = new BufferCreateInfo
|
||||
{
|
||||
SType = StructureType.BufferCreateInfo,
|
||||
Size = (ulong)size,
|
||||
Usage = usage,
|
||||
SharingMode = SharingMode.Exclusive
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
};
|
||||
|
||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
||||
@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
BufferAllocationType.HostMapped => DefaultBufferMemoryFlags,
|
||||
BufferAllocationType.DeviceLocal => DeviceLocalBufferMemoryFlags,
|
||||
BufferAllocationType.DeviceLocalMapped => DeviceLocalMappedBufferMemoryFlags,
|
||||
_ => DefaultBufferMemoryFlags
|
||||
_ => DefaultBufferMemoryFlags,
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
public unsafe BufferHolder Create(
|
||||
public BufferHolder Create(
|
||||
VulkanRenderer gd,
|
||||
int size,
|
||||
bool forConditionalRendering = false,
|
||||
|
@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
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 _size;
|
||||
@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
buffer?.IncrementReferenceCount();
|
||||
}
|
||||
|
||||
public void BindTransformFeedbackBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding)
|
||||
public readonly void BindTransformFeedbackBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding)
|
||||
{
|
||||
if (_buffer != null)
|
||||
{
|
||||
@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
_buffer?.DecrementReferenceCount();
|
||||
}
|
||||
|
@ -2,13 +2,13 @@
|
||||
{
|
||||
internal class BufferUsageBitmap
|
||||
{
|
||||
private BitMap _bitmap;
|
||||
private int _size;
|
||||
private int _granularity;
|
||||
private int _bits;
|
||||
private readonly BitMap _bitmap;
|
||||
private readonly int _size;
|
||||
private readonly int _granularity;
|
||||
private readonly int _bits;
|
||||
|
||||
private int _intsPerCb;
|
||||
private int _bitsPerCb;
|
||||
private readonly int _intsPerCb;
|
||||
private readonly int _bitsPerCb;
|
||||
|
||||
public BufferUsageBitmap(int size, int granularity)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = null;
|
||||
}
|
||||
|
||||
public bool KeyEqual(ICacheKey other)
|
||||
public readonly bool KeyEqual(ICacheKey other)
|
||||
{
|
||||
return other is I8ToI16CacheKey;
|
||||
}
|
||||
@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
_gd.PipelineInternal.DirtyIndexBuffer(_buffer);
|
||||
}
|
||||
@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = null;
|
||||
}
|
||||
|
||||
public bool KeyEqual(ICacheKey other)
|
||||
public readonly bool KeyEqual(ICacheKey other)
|
||||
{
|
||||
return other is AlignedVertexBufferCacheKey entry &&
|
||||
entry._stride == _stride &&
|
||||
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
_gd.PipelineInternal.DirtyVertexBuffer(_buffer);
|
||||
}
|
||||
@ -73,8 +73,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
struct TopologyConversionCacheKey : ICacheKey
|
||||
{
|
||||
private IndexBufferPattern _pattern;
|
||||
private int _indexSize;
|
||||
private readonly IndexBufferPattern _pattern;
|
||||
private readonly int _indexSize;
|
||||
|
||||
// Used to notify the pipeline that bindings have invalidated on dispose.
|
||||
private readonly VulkanRenderer _gd;
|
||||
@ -88,7 +88,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = null;
|
||||
}
|
||||
|
||||
public bool KeyEqual(ICacheKey other)
|
||||
public readonly bool KeyEqual(ICacheKey other)
|
||||
{
|
||||
return other is TopologyConversionCacheKey entry &&
|
||||
entry._pattern == _pattern &&
|
||||
@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
_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)
|
||||
{
|
||||
@ -168,12 +168,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
struct DrawCountCacheKey : ICacheKey
|
||||
{
|
||||
public bool KeyEqual(ICacheKey other)
|
||||
public readonly bool KeyEqual(ICacheKey other)
|
||||
{
|
||||
return other is DrawCountCacheKey;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -214,7 +214,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DependencyList = null;
|
||||
}
|
||||
|
||||
public void InvalidateDependencies()
|
||||
public readonly void InvalidateDependencies()
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -356,15 +356,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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);
|
||||
|
||||
List<Entry> value;
|
||||
if (!_ranges.TryGetValue(key, out value))
|
||||
if (!_ranges.TryGetValue(key, out List<Entry> value))
|
||||
{
|
||||
value = new List<Entry>();
|
||||
_ranges.Add(key, value);
|
||||
|
@ -2,7 +2,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Thread = System.Threading.Thread;
|
||||
using System.Threading;
|
||||
using Semaphore = Silk.NET.Vulkan.Semaphore;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@ -10,8 +11,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
public const int MaxCommandBuffers = 16;
|
||||
|
||||
private int _totalCommandBuffers;
|
||||
private int _totalCommandBuffersMask;
|
||||
private readonly int _totalCommandBuffers;
|
||||
private readonly int _totalCommandBuffersMask;
|
||||
|
||||
private readonly Vk _api;
|
||||
private readonly Device _device;
|
||||
@ -36,12 +37,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void Initialize(Vk api, Device device, CommandPool pool)
|
||||
{
|
||||
var allocateInfo = new CommandBufferAllocateInfo()
|
||||
var allocateInfo = new CommandBufferAllocateInfo
|
||||
{
|
||||
SType = StructureType.CommandBufferAllocateInfo,
|
||||
CommandBufferCount = 1,
|
||||
CommandPool = pool,
|
||||
Level = CommandBufferLevel.Primary
|
||||
Level = CommandBufferLevel.Primary,
|
||||
};
|
||||
|
||||
api.AllocateCommandBuffers(device, allocateInfo, out CommandBuffer);
|
||||
@ -67,12 +68,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_queueLock = queueLock;
|
||||
_owner = Thread.CurrentThread;
|
||||
|
||||
var commandPoolCreateInfo = new CommandPoolCreateInfo()
|
||||
var commandPoolCreateInfo = new CommandPoolCreateInfo
|
||||
{
|
||||
SType = StructureType.CommandPoolCreateInfo,
|
||||
QueueFamilyIndex = queueFamilyIndex,
|
||||
Flags = CommandPoolCreateFlags.TransientBit |
|
||||
CommandPoolCreateFlags.ResetCommandBufferBit
|
||||
CommandPoolCreateFlags.ResetCommandBufferBit,
|
||||
};
|
||||
|
||||
api.CreateCommandPool(device, commandPoolCreateInfo, null, out _pool).ThrowOnError();
|
||||
@ -243,9 +244,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_inUseCount++;
|
||||
|
||||
var commandBufferBeginInfo = new CommandBufferBeginInfo()
|
||||
var commandBufferBeginInfo = new CommandBufferBeginInfo
|
||||
{
|
||||
SType = StructureType.CommandBufferBeginInfo
|
||||
SType = StructureType.CommandBufferBeginInfo,
|
||||
};
|
||||
|
||||
_api.BeginCommandBuffer(entry.CommandBuffer, commandBufferBeginInfo).ThrowOnError();
|
||||
@ -291,7 +292,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
fixed (PipelineStageFlags* pWaitDstStageMask = waitDstStageMask)
|
||||
{
|
||||
SubmitInfo sInfo = new SubmitInfo()
|
||||
SubmitInfo sInfo = new()
|
||||
{
|
||||
SType = StructureType.SubmitInfo,
|
||||
WaitSemaphoreCount = waitSemaphores != null ? (uint)waitSemaphores.Length : 0,
|
||||
@ -300,7 +301,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
CommandBufferCount = 1,
|
||||
PCommandBuffers = &commandBuffer,
|
||||
SignalSemaphoreCount = signalSemaphores != null ? (uint)signalSemaphores.Length : 0,
|
||||
PSignalSemaphores = pSignalSemaphores
|
||||
PSignalSemaphores = pSignalSemaphores,
|
||||
};
|
||||
|
||||
lock (_queueLock)
|
||||
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
private DescriptorSetManager.DescriptorPoolHolder _holder;
|
||||
private readonly DescriptorSet[] _descriptorSets;
|
||||
public int SetsCount => _descriptorSets.Length;
|
||||
public readonly int SetsCount => _descriptorSets.Length;
|
||||
|
||||
public DescriptorSetCollection(DescriptorSetManager.DescriptorPoolHolder holder, DescriptorSet[] descriptorSets)
|
||||
{
|
||||
@ -20,10 +20,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[count];
|
||||
|
||||
infos.Fill(new DescriptorBufferInfo()
|
||||
infos.Fill(new DescriptorBufferInfo
|
||||
{
|
||||
Buffer = dummyBuffer,
|
||||
Range = Vk.WholeSize
|
||||
Range = Vk.WholeSize,
|
||||
});
|
||||
|
||||
UpdateBuffers(setIndex, baseBinding, infos, type);
|
||||
@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)bindingIndex,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = 1,
|
||||
PBufferInfo = &bufferInfo
|
||||
PBufferInfo = &bufferInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@ -63,7 +63,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)baseBinding,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = (uint)bufferInfo.Length,
|
||||
PBufferInfo = pBufferInfo
|
||||
PBufferInfo = pBufferInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)bindingIndex,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = 1,
|
||||
PImageInfo = &imageInfo
|
||||
PImageInfo = &imageInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)baseBinding,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = (uint)imageInfo.Length,
|
||||
PImageInfo = pImageInfo
|
||||
PImageInfo = pImageInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@ -141,7 +141,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)(baseBinding + i),
|
||||
DescriptorType = DescriptorType.CombinedImageSampler,
|
||||
DescriptorCount = (uint)count,
|
||||
PImageInfo = pImageInfo
|
||||
PImageInfo = pImageInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@ -163,7 +163,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)bindingIndex,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = 1,
|
||||
PTexelBufferView = &texelBufferView
|
||||
PTexelBufferView = &texelBufferView,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)baseBinding + i,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = count,
|
||||
PTexelBufferView = pTexelBufferView + i
|
||||
PTexelBufferView = pTexelBufferView + i,
|
||||
};
|
||||
|
||||
_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;
|
||||
}
|
||||
|
@ -24,14 +24,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Api = api;
|
||||
Device = device;
|
||||
|
||||
var poolSizes = new DescriptorPoolSize[]
|
||||
var poolSizes = new[]
|
||||
{
|
||||
new DescriptorPoolSize(DescriptorType.UniformBuffer, (1 + Constants.MaxUniformBufferBindings) * DescriptorPoolMultiplier),
|
||||
new DescriptorPoolSize(DescriptorType.StorageBuffer, Constants.MaxStorageBufferBindings * DescriptorPoolMultiplier),
|
||||
new DescriptorPoolSize(DescriptorType.CombinedImageSampler, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
|
||||
new DescriptorPoolSize(DescriptorType.StorageImage, Constants.MaxImageBindings * 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;
|
||||
@ -40,19 +40,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (DescriptorPoolSize* pPoolsSize = poolSizes)
|
||||
{
|
||||
var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo()
|
||||
var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo
|
||||
{
|
||||
SType = StructureType.DescriptorPoolCreateInfo,
|
||||
MaxSets = maxSets,
|
||||
PoolSizeCount = (uint)poolSizes.Length,
|
||||
PPoolSizes = pPoolsSize
|
||||
PPoolSizes = pPoolsSize,
|
||||
};
|
||||
|
||||
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);
|
||||
return dsc;
|
||||
@ -73,12 +73,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
fixed (DescriptorSetLayout* pLayouts = layouts)
|
||||
{
|
||||
var descriptorSetAllocateInfo = new DescriptorSetAllocateInfo()
|
||||
var descriptorSetAllocateInfo = new DescriptorSetAllocateInfo
|
||||
{
|
||||
SType = StructureType.DescriptorSetAllocateInfo,
|
||||
DescriptorPool = _pool,
|
||||
DescriptorSetCount = (uint)layouts.Length,
|
||||
PSetLayouts = pLayouts
|
||||
PSetLayouts = pLayouts,
|
||||
};
|
||||
|
||||
var result = Api.AllocateDescriptorSets(Device, &descriptorSetAllocateInfo, pDescriptorSets);
|
||||
@ -142,6 +142,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
@ -186,15 +187,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
_currentPool?.Dispose();
|
||||
}
|
||||
_currentPool?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,11 @@
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
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
|
||||
{
|
||||
@ -14,25 +17,25 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private ShaderCollection _program;
|
||||
|
||||
private Auto<DisposableBuffer>[] _uniformBufferRefs;
|
||||
private Auto<DisposableBuffer>[] _storageBufferRefs;
|
||||
private Auto<DisposableImageView>[] _textureRefs;
|
||||
private Auto<DisposableSampler>[] _samplerRefs;
|
||||
private Auto<DisposableImageView>[] _imageRefs;
|
||||
private TextureBuffer[] _bufferTextureRefs;
|
||||
private TextureBuffer[] _bufferImageRefs;
|
||||
private GAL.Format[] _bufferImageFormats;
|
||||
private readonly Auto<DisposableBuffer>[] _uniformBufferRefs;
|
||||
private readonly Auto<DisposableBuffer>[] _storageBufferRefs;
|
||||
private readonly Auto<DisposableImageView>[] _textureRefs;
|
||||
private readonly Auto<DisposableSampler>[] _samplerRefs;
|
||||
private readonly Auto<DisposableImageView>[] _imageRefs;
|
||||
private readonly TextureBuffer[] _bufferTextureRefs;
|
||||
private readonly TextureBuffer[] _bufferImageRefs;
|
||||
private readonly Format[] _bufferImageFormats;
|
||||
|
||||
private DescriptorBufferInfo[] _uniformBuffers;
|
||||
private DescriptorBufferInfo[] _storageBuffers;
|
||||
private DescriptorImageInfo[] _textures;
|
||||
private DescriptorImageInfo[] _images;
|
||||
private BufferView[] _bufferTextures;
|
||||
private BufferView[] _bufferImages;
|
||||
private readonly DescriptorBufferInfo[] _uniformBuffers;
|
||||
private readonly DescriptorBufferInfo[] _storageBuffers;
|
||||
private readonly DescriptorImageInfo[] _textures;
|
||||
private readonly DescriptorImageInfo[] _images;
|
||||
private readonly BufferView[] _bufferTextures;
|
||||
private readonly BufferView[] _bufferImages;
|
||||
|
||||
private bool[] _uniformSet;
|
||||
private bool[] _storageSet;
|
||||
private Silk.NET.Vulkan.Buffer _cachedSupportBuffer;
|
||||
private readonly bool[] _uniformSet;
|
||||
private readonly bool[] _storageSet;
|
||||
private Buffer _cachedSupportBuffer;
|
||||
|
||||
[Flags]
|
||||
private enum DirtyFlags
|
||||
@ -42,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Storage = 1 << 1,
|
||||
Texture = 1 << 2,
|
||||
Image = 1 << 3,
|
||||
All = Uniform | Storage | Texture | Image
|
||||
All = Uniform | Storage | Texture | Image,
|
||||
}
|
||||
|
||||
private DirtyFlags _dirty;
|
||||
@ -66,7 +69,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_imageRefs = new Auto<DisposableImageView>[Constants.MaxImageBindings * 2];
|
||||
_bufferTextureRefs = new TextureBuffer[Constants.MaxTextureBindings * 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];
|
||||
_storageBuffers = new DescriptorBufferInfo[Constants.MaxStorageBufferBindings];
|
||||
@ -75,9 +78,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_bufferTextures = new BufferView[Constants.MaxTexturesPerStage];
|
||||
_bufferImages = new BufferView[Constants.MaxImagesPerStage];
|
||||
|
||||
var initialImageInfo = new DescriptorImageInfo()
|
||||
var initialImageInfo = new DescriptorImageInfo
|
||||
{
|
||||
ImageLayout = ImageLayout.General
|
||||
ImageLayout = ImageLayout.General,
|
||||
};
|
||||
|
||||
_textures.AsSpan().Fill(initialImageInfo);
|
||||
@ -106,7 +109,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
1,
|
||||
1,
|
||||
4,
|
||||
GAL.Format.R8G8B8A8Unorm,
|
||||
Format.R8G8B8A8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
@ -114,7 +117,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SwizzleComponent.Blue,
|
||||
SwizzleComponent.Alpha), 1f);
|
||||
|
||||
_dummySampler = (SamplerHolder)gd.CreateSampler(new GAL.SamplerCreateInfo(
|
||||
_dummySampler = (SamplerHolder)gd.CreateSampler(new SamplerCreateInfo(
|
||||
MinFilter.Nearest,
|
||||
MagFilter.Nearest,
|
||||
false,
|
||||
@ -122,7 +125,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
AddressMode.Repeat,
|
||||
AddressMode.Repeat,
|
||||
CompareMode.None,
|
||||
GAL.CompareOp.Always,
|
||||
CompareOp.Always,
|
||||
new ColorF(0, 0, 0, 0),
|
||||
0,
|
||||
0,
|
||||
@ -142,7 +145,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_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)
|
||||
{
|
||||
@ -181,10 +184,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false, isSSBO: true);
|
||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
||||
|
||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
||||
DescriptorBufferInfo info = new()
|
||||
{
|
||||
Offset = (ulong)buffer.Offset,
|
||||
Range = (ulong)buffer.Size
|
||||
Range = (ulong)buffer.Size,
|
||||
};
|
||||
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
||||
|
||||
@ -209,10 +212,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
||||
|
||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
||||
DescriptorBufferInfo info = new()
|
||||
{
|
||||
Offset = 0,
|
||||
Range = Vk.WholeSize
|
||||
Range = Vk.WholeSize,
|
||||
};
|
||||
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
||||
|
||||
@ -289,10 +292,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
|
||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _uniformBufferRefs[index];
|
||||
|
||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
||||
DescriptorBufferInfo info = new()
|
||||
{
|
||||
Offset = (ulong)buffer.Offset,
|
||||
Range = (ulong)buffer.Size
|
||||
Range = (ulong)buffer.Size,
|
||||
};
|
||||
ref DescriptorBufferInfo currentInfo = ref _uniformBuffers[index];
|
||||
|
||||
@ -400,11 +403,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_uniformSet[0] = true;
|
||||
}
|
||||
|
||||
uniformBuffer[0] = new DescriptorBufferInfo()
|
||||
uniformBuffer[0] = new DescriptorBufferInfo
|
||||
{
|
||||
Offset = 0,
|
||||
Range = (ulong)SupportBuffer.RequiredSize,
|
||||
Buffer = _cachedSupportBuffer
|
||||
Buffer = _cachedSupportBuffer,
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
@ -485,7 +488,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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)
|
||||
@ -499,7 +502,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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
|
||||
{
|
||||
@ -510,7 +513,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = (uint)bufferInfo.Length,
|
||||
PBufferInfo = pBufferInfo
|
||||
PBufferInfo = pBufferInfo,
|
||||
};
|
||||
|
||||
_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];
|
||||
|
||||
uniformBuffer[0] = new DescriptorBufferInfo()
|
||||
uniformBuffer[0] = new DescriptorBufferInfo
|
||||
{
|
||||
Offset = 0,
|
||||
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;
|
||||
@ -620,7 +623,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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++)
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@ -8,9 +9,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Vk _api;
|
||||
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;
|
||||
_device = device;
|
||||
|
@ -5,10 +5,12 @@ using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Extent2D = Ryujinx.Graphics.GAL.Extents2D;
|
||||
using Format = Silk.NET.Vulkan.Format;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal partial class FsrScalingFilter : IScalingFilter
|
||||
internal class FsrScalingFilter : IScalingFilter
|
||||
{
|
||||
private readonly VulkanRenderer _renderer;
|
||||
private PipelineHelperShader _pipeline;
|
||||
@ -66,16 +68,16 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||
.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[]
|
||||
{
|
||||
new ShaderSource(scalingShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(scalingShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, scalingResourceLayout);
|
||||
|
||||
_sharpeningProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(sharpeningShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(sharpeningShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, sharpeningResourceLayout);
|
||||
}
|
||||
|
||||
@ -83,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
TextureView view,
|
||||
CommandBufferScoped cbs,
|
||||
Auto<DisposableImageView> destinationTexture,
|
||||
Silk.NET.Vulkan.Format format,
|
||||
Format format,
|
||||
int width,
|
||||
int height,
|
||||
Extent2D source,
|
||||
@ -136,14 +138,14 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
destination.Y1,
|
||||
destination.Y2,
|
||||
scaleX,
|
||||
scaleY
|
||||
scaleY,
|
||||
};
|
||||
|
||||
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
||||
var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize);
|
||||
_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));
|
||||
_renderer.BufferManager.SetData(sharpeningBufferHandle, 0, sharpeningBuffer);
|
||||
|
||||
@ -172,4 +174,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
_renderer.BufferManager.Delete(sharpeningBufferHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,16 +4,17 @@ using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal partial class FxaaPostProcessingEffect : IPostProcessingEffect
|
||||
internal class FxaaPostProcessingEffect : IPostProcessingEffect
|
||||
{
|
||||
private readonly VulkanRenderer _renderer;
|
||||
private ISampler _samplerLinear;
|
||||
private ShaderCollection _shaderProgram;
|
||||
|
||||
private PipelineHelperShader _pipeline;
|
||||
private readonly PipelineHelperShader _pipeline;
|
||||
private TextureView _texture;
|
||||
|
||||
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.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[]
|
||||
{
|
||||
new ShaderSource(shader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(shader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, resourceLayout);
|
||||
}
|
||||
|
||||
@ -86,4 +87,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
return _texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,4 +7,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
const int LocalGroupSize = 64;
|
||||
TextureView Run(TextureView view, CommandBufferScoped cbs, int width, int height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,4 +17,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
Extent2D source,
|
||||
Extent2D destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,4 +12,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
public float Width;
|
||||
public float Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,12 @@ using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal partial class SmaaPostProcessingEffect : IPostProcessingEffect
|
||||
internal class SmaaPostProcessingEffect : IPostProcessingEffect
|
||||
{
|
||||
public const int AreaWidth = 160;
|
||||
public const int AreaHeight = 560;
|
||||
@ -63,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
_searchTexture?.Dispose();
|
||||
}
|
||||
|
||||
private unsafe void RecreateShaders(int width, int height)
|
||||
private void RecreateShaders(int width, int height)
|
||||
{
|
||||
_recreatePipelines = false;
|
||||
|
||||
@ -94,9 +96,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 3)
|
||||
.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,
|
||||
Height = height,
|
||||
@ -116,17 +118,17 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
|
||||
_edgeProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(edgeShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(edgeShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, edgeResourceLayout, new[] { specInfo });
|
||||
|
||||
_blendProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(blendShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(blendShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, blendResourceLayout, new[] { specInfo });
|
||||
|
||||
_neighbourProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(neighbourShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(neighbourShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, neighbourResourceLayout, new[] { specInfo });
|
||||
}
|
||||
|
||||
@ -148,7 +150,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
GAL.Format.R8G8Unorm,
|
||||
Format.R8G8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
@ -164,7 +166,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
GAL.Format.R8Unorm,
|
||||
Format.R8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
@ -264,4 +266,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
_pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,14 @@ using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.Vulkan;
|
||||
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
|
||||
{
|
||||
@ -18,7 +26,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ShaderStage.TessellationEvaluation => ShaderStageFlags.TessellationEvaluationBit,
|
||||
ShaderStage.Fragment => ShaderStageFlags.FragmentBit,
|
||||
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.Fragment => PipelineStageFlags.FragmentShaderBit,
|
||||
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.BufferTexture => DescriptorType.UniformTexelBuffer,
|
||||
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.MirroredRepeat => SamplerAddressMode.MirroredRepeat,
|
||||
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
|
||||
{
|
||||
GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => Silk.NET.Vulkan.BlendFactor.Zero,
|
||||
GAL.BlendFactor.One or GAL.BlendFactor.OneGl => Silk.NET.Vulkan.BlendFactor.One,
|
||||
GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => Silk.NET.Vulkan.BlendFactor.SrcColor,
|
||||
GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrcColor,
|
||||
GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => Silk.NET.Vulkan.BlendFactor.SrcAlpha,
|
||||
GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrcAlpha,
|
||||
GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => Silk.NET.Vulkan.BlendFactor.DstAlpha,
|
||||
GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusDstAlpha,
|
||||
GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => Silk.NET.Vulkan.BlendFactor.DstColor,
|
||||
GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusDstColor,
|
||||
GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => Silk.NET.Vulkan.BlendFactor.SrcAlphaSaturate,
|
||||
GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => Silk.NET.Vulkan.BlendFactor.Src1Color,
|
||||
GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrc1Color,
|
||||
GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => Silk.NET.Vulkan.BlendFactor.Src1Alpha,
|
||||
GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrc1Alpha,
|
||||
GAL.BlendFactor.ConstantColor => Silk.NET.Vulkan.BlendFactor.ConstantColor,
|
||||
GAL.BlendFactor.OneMinusConstantColor => Silk.NET.Vulkan.BlendFactor.OneMinusConstantColor,
|
||||
GAL.BlendFactor.ConstantAlpha => Silk.NET.Vulkan.BlendFactor.ConstantAlpha,
|
||||
GAL.BlendFactor.OneMinusConstantAlpha => Silk.NET.Vulkan.BlendFactor.OneMinusConstantAlpha,
|
||||
_ => LogInvalidAndReturn(factor, nameof(GAL.BlendFactor), Silk.NET.Vulkan.BlendFactor.Zero)
|
||||
GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => BlendFactor.Zero,
|
||||
GAL.BlendFactor.One or GAL.BlendFactor.OneGl => BlendFactor.One,
|
||||
GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => BlendFactor.SrcColor,
|
||||
GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => BlendFactor.OneMinusSrcColor,
|
||||
GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => BlendFactor.SrcAlpha,
|
||||
GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => BlendFactor.OneMinusSrcAlpha,
|
||||
GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => BlendFactor.DstAlpha,
|
||||
GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => BlendFactor.OneMinusDstAlpha,
|
||||
GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => BlendFactor.DstColor,
|
||||
GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => BlendFactor.OneMinusDstColor,
|
||||
GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => BlendFactor.SrcAlphaSaturate,
|
||||
GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => BlendFactor.Src1Color,
|
||||
GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => BlendFactor.OneMinusSrc1Color,
|
||||
GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => BlendFactor.Src1Alpha,
|
||||
GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => BlendFactor.OneMinusSrc1Alpha,
|
||||
GAL.BlendFactor.ConstantColor => BlendFactor.ConstantColor,
|
||||
GAL.BlendFactor.OneMinusConstantColor => BlendFactor.OneMinusConstantColor,
|
||||
GAL.BlendFactor.ConstantAlpha => BlendFactor.ConstantAlpha,
|
||||
GAL.BlendFactor.OneMinusConstantAlpha => BlendFactor.OneMinusConstantAlpha,
|
||||
_ => 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
|
||||
{
|
||||
GAL.AdvancedBlendOp.Zero => Silk.NET.Vulkan.BlendOp.ZeroExt,
|
||||
GAL.AdvancedBlendOp.Src => Silk.NET.Vulkan.BlendOp.SrcExt,
|
||||
GAL.AdvancedBlendOp.Dst => Silk.NET.Vulkan.BlendOp.DstExt,
|
||||
GAL.AdvancedBlendOp.SrcOver => Silk.NET.Vulkan.BlendOp.SrcOverExt,
|
||||
GAL.AdvancedBlendOp.DstOver => Silk.NET.Vulkan.BlendOp.DstOverExt,
|
||||
GAL.AdvancedBlendOp.SrcIn => Silk.NET.Vulkan.BlendOp.SrcInExt,
|
||||
GAL.AdvancedBlendOp.DstIn => Silk.NET.Vulkan.BlendOp.DstInExt,
|
||||
GAL.AdvancedBlendOp.SrcOut => Silk.NET.Vulkan.BlendOp.SrcOutExt,
|
||||
GAL.AdvancedBlendOp.DstOut => Silk.NET.Vulkan.BlendOp.DstOutExt,
|
||||
GAL.AdvancedBlendOp.SrcAtop => Silk.NET.Vulkan.BlendOp.SrcAtopExt,
|
||||
GAL.AdvancedBlendOp.DstAtop => Silk.NET.Vulkan.BlendOp.DstAtopExt,
|
||||
GAL.AdvancedBlendOp.Xor => Silk.NET.Vulkan.BlendOp.XorExt,
|
||||
GAL.AdvancedBlendOp.Plus => Silk.NET.Vulkan.BlendOp.PlusExt,
|
||||
GAL.AdvancedBlendOp.PlusClamped => Silk.NET.Vulkan.BlendOp.PlusClampedExt,
|
||||
GAL.AdvancedBlendOp.PlusClampedAlpha => Silk.NET.Vulkan.BlendOp.PlusClampedAlphaExt,
|
||||
GAL.AdvancedBlendOp.PlusDarker => Silk.NET.Vulkan.BlendOp.PlusDarkerExt,
|
||||
GAL.AdvancedBlendOp.Multiply => Silk.NET.Vulkan.BlendOp.MultiplyExt,
|
||||
GAL.AdvancedBlendOp.Screen => Silk.NET.Vulkan.BlendOp.ScreenExt,
|
||||
GAL.AdvancedBlendOp.Overlay => Silk.NET.Vulkan.BlendOp.OverlayExt,
|
||||
GAL.AdvancedBlendOp.Darken => Silk.NET.Vulkan.BlendOp.DarkenExt,
|
||||
GAL.AdvancedBlendOp.Lighten => Silk.NET.Vulkan.BlendOp.LightenExt,
|
||||
GAL.AdvancedBlendOp.ColorDodge => Silk.NET.Vulkan.BlendOp.ColordodgeExt,
|
||||
GAL.AdvancedBlendOp.ColorBurn => Silk.NET.Vulkan.BlendOp.ColorburnExt,
|
||||
GAL.AdvancedBlendOp.HardLight => Silk.NET.Vulkan.BlendOp.HardlightExt,
|
||||
GAL.AdvancedBlendOp.SoftLight => Silk.NET.Vulkan.BlendOp.SoftlightExt,
|
||||
GAL.AdvancedBlendOp.Difference => Silk.NET.Vulkan.BlendOp.DifferenceExt,
|
||||
GAL.AdvancedBlendOp.Minus => Silk.NET.Vulkan.BlendOp.MinusExt,
|
||||
GAL.AdvancedBlendOp.MinusClamped => Silk.NET.Vulkan.BlendOp.MinusClampedExt,
|
||||
GAL.AdvancedBlendOp.Exclusion => Silk.NET.Vulkan.BlendOp.ExclusionExt,
|
||||
GAL.AdvancedBlendOp.Contrast => Silk.NET.Vulkan.BlendOp.ContrastExt,
|
||||
GAL.AdvancedBlendOp.Invert => Silk.NET.Vulkan.BlendOp.InvertExt,
|
||||
GAL.AdvancedBlendOp.InvertRGB => Silk.NET.Vulkan.BlendOp.InvertRgbExt,
|
||||
GAL.AdvancedBlendOp.InvertOvg => Silk.NET.Vulkan.BlendOp.InvertOvgExt,
|
||||
GAL.AdvancedBlendOp.LinearDodge => Silk.NET.Vulkan.BlendOp.LineardodgeExt,
|
||||
GAL.AdvancedBlendOp.LinearBurn => Silk.NET.Vulkan.BlendOp.LinearburnExt,
|
||||
GAL.AdvancedBlendOp.VividLight => Silk.NET.Vulkan.BlendOp.VividlightExt,
|
||||
GAL.AdvancedBlendOp.LinearLight => Silk.NET.Vulkan.BlendOp.LinearlightExt,
|
||||
GAL.AdvancedBlendOp.PinLight => Silk.NET.Vulkan.BlendOp.PinlightExt,
|
||||
GAL.AdvancedBlendOp.HardMix => Silk.NET.Vulkan.BlendOp.HardmixExt,
|
||||
GAL.AdvancedBlendOp.Red => Silk.NET.Vulkan.BlendOp.RedExt,
|
||||
GAL.AdvancedBlendOp.Green => Silk.NET.Vulkan.BlendOp.GreenExt,
|
||||
GAL.AdvancedBlendOp.Blue => Silk.NET.Vulkan.BlendOp.BlueExt,
|
||||
GAL.AdvancedBlendOp.HslHue => Silk.NET.Vulkan.BlendOp.HslHueExt,
|
||||
GAL.AdvancedBlendOp.HslSaturation => Silk.NET.Vulkan.BlendOp.HslSaturationExt,
|
||||
GAL.AdvancedBlendOp.HslColor => Silk.NET.Vulkan.BlendOp.HslColorExt,
|
||||
GAL.AdvancedBlendOp.HslLuminosity => Silk.NET.Vulkan.BlendOp.HslLuminosityExt,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.AdvancedBlendOp), Silk.NET.Vulkan.BlendOp.Add)
|
||||
AdvancedBlendOp.Zero => BlendOp.ZeroExt,
|
||||
AdvancedBlendOp.Src => BlendOp.SrcExt,
|
||||
AdvancedBlendOp.Dst => BlendOp.DstExt,
|
||||
AdvancedBlendOp.SrcOver => BlendOp.SrcOverExt,
|
||||
AdvancedBlendOp.DstOver => BlendOp.DstOverExt,
|
||||
AdvancedBlendOp.SrcIn => BlendOp.SrcInExt,
|
||||
AdvancedBlendOp.DstIn => BlendOp.DstInExt,
|
||||
AdvancedBlendOp.SrcOut => BlendOp.SrcOutExt,
|
||||
AdvancedBlendOp.DstOut => BlendOp.DstOutExt,
|
||||
AdvancedBlendOp.SrcAtop => BlendOp.SrcAtopExt,
|
||||
AdvancedBlendOp.DstAtop => BlendOp.DstAtopExt,
|
||||
AdvancedBlendOp.Xor => BlendOp.XorExt,
|
||||
AdvancedBlendOp.Plus => BlendOp.PlusExt,
|
||||
AdvancedBlendOp.PlusClamped => BlendOp.PlusClampedExt,
|
||||
AdvancedBlendOp.PlusClampedAlpha => BlendOp.PlusClampedAlphaExt,
|
||||
AdvancedBlendOp.PlusDarker => BlendOp.PlusDarkerExt,
|
||||
AdvancedBlendOp.Multiply => BlendOp.MultiplyExt,
|
||||
AdvancedBlendOp.Screen => BlendOp.ScreenExt,
|
||||
AdvancedBlendOp.Overlay => BlendOp.OverlayExt,
|
||||
AdvancedBlendOp.Darken => BlendOp.DarkenExt,
|
||||
AdvancedBlendOp.Lighten => BlendOp.LightenExt,
|
||||
AdvancedBlendOp.ColorDodge => BlendOp.ColordodgeExt,
|
||||
AdvancedBlendOp.ColorBurn => BlendOp.ColorburnExt,
|
||||
AdvancedBlendOp.HardLight => BlendOp.HardlightExt,
|
||||
AdvancedBlendOp.SoftLight => BlendOp.SoftlightExt,
|
||||
AdvancedBlendOp.Difference => BlendOp.DifferenceExt,
|
||||
AdvancedBlendOp.Minus => BlendOp.MinusExt,
|
||||
AdvancedBlendOp.MinusClamped => BlendOp.MinusClampedExt,
|
||||
AdvancedBlendOp.Exclusion => BlendOp.ExclusionExt,
|
||||
AdvancedBlendOp.Contrast => BlendOp.ContrastExt,
|
||||
AdvancedBlendOp.Invert => BlendOp.InvertExt,
|
||||
AdvancedBlendOp.InvertRGB => BlendOp.InvertRgbExt,
|
||||
AdvancedBlendOp.InvertOvg => BlendOp.InvertOvgExt,
|
||||
AdvancedBlendOp.LinearDodge => BlendOp.LineardodgeExt,
|
||||
AdvancedBlendOp.LinearBurn => BlendOp.LinearburnExt,
|
||||
AdvancedBlendOp.VividLight => BlendOp.VividlightExt,
|
||||
AdvancedBlendOp.LinearLight => BlendOp.LinearlightExt,
|
||||
AdvancedBlendOp.PinLight => BlendOp.PinlightExt,
|
||||
AdvancedBlendOp.HardMix => BlendOp.HardmixExt,
|
||||
AdvancedBlendOp.Red => BlendOp.RedExt,
|
||||
AdvancedBlendOp.Green => BlendOp.GreenExt,
|
||||
AdvancedBlendOp.Blue => BlendOp.BlueExt,
|
||||
AdvancedBlendOp.HslHue => BlendOp.HslHueExt,
|
||||
AdvancedBlendOp.HslSaturation => BlendOp.HslSaturationExt,
|
||||
AdvancedBlendOp.HslColor => BlendOp.HslColorExt,
|
||||
AdvancedBlendOp.HslLuminosity => BlendOp.HslLuminosityExt,
|
||||
_ => 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
|
||||
{
|
||||
GAL.BlendOp.Add or GAL.BlendOp.AddGl => Silk.NET.Vulkan.BlendOp.Add,
|
||||
GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => Silk.NET.Vulkan.BlendOp.Subtract,
|
||||
GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => Silk.NET.Vulkan.BlendOp.ReverseSubtract,
|
||||
GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => Silk.NET.Vulkan.BlendOp.Min,
|
||||
GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => Silk.NET.Vulkan.BlendOp.Max,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.BlendOp), Silk.NET.Vulkan.BlendOp.Add)
|
||||
GAL.BlendOp.Add or GAL.BlendOp.AddGl => BlendOp.Add,
|
||||
GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => BlendOp.Subtract,
|
||||
GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => BlendOp.ReverseSubtract,
|
||||
GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => BlendOp.Min,
|
||||
GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => BlendOp.Max,
|
||||
_ => 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
|
||||
{
|
||||
GAL.AdvancedBlendOverlap.Uncorrelated => Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt,
|
||||
GAL.AdvancedBlendOverlap.Disjoint => Silk.NET.Vulkan.BlendOverlapEXT.DisjointExt,
|
||||
GAL.AdvancedBlendOverlap.Conjoint => Silk.NET.Vulkan.BlendOverlapEXT.ConjointExt,
|
||||
_ => LogInvalidAndReturn(overlap, nameof(GAL.AdvancedBlendOverlap), Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt)
|
||||
AdvancedBlendOverlap.Uncorrelated => BlendOverlapEXT.UncorrelatedExt,
|
||||
AdvancedBlendOverlap.Disjoint => BlendOverlapEXT.DisjointExt,
|
||||
AdvancedBlendOverlap.Conjoint => BlendOverlapEXT.ConjointExt,
|
||||
_ => 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
|
||||
{
|
||||
GAL.CompareOp.Never or GAL.CompareOp.NeverGl => Silk.NET.Vulkan.CompareOp.Never,
|
||||
GAL.CompareOp.Less or GAL.CompareOp.LessGl => Silk.NET.Vulkan.CompareOp.Less,
|
||||
GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => Silk.NET.Vulkan.CompareOp.Equal,
|
||||
GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => Silk.NET.Vulkan.CompareOp.LessOrEqual,
|
||||
GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => Silk.NET.Vulkan.CompareOp.Greater,
|
||||
GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => Silk.NET.Vulkan.CompareOp.NotEqual,
|
||||
GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => Silk.NET.Vulkan.CompareOp.GreaterOrEqual,
|
||||
GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => Silk.NET.Vulkan.CompareOp.Always,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), Silk.NET.Vulkan.CompareOp.Never)
|
||||
GAL.CompareOp.Never or GAL.CompareOp.NeverGl => CompareOp.Never,
|
||||
GAL.CompareOp.Less or GAL.CompareOp.LessGl => CompareOp.Less,
|
||||
GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => CompareOp.Equal,
|
||||
GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => CompareOp.LessOrEqual,
|
||||
GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => CompareOp.Greater,
|
||||
GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => CompareOp.NotEqual,
|
||||
GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => CompareOp.GreaterOrEqual,
|
||||
GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => CompareOp.Always,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), CompareOp.Never),
|
||||
};
|
||||
}
|
||||
|
||||
@ -230,29 +238,29 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Face.Back => CullModeFlags.BackBit,
|
||||
Face.Front => CullModeFlags.FrontBit,
|
||||
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.
|
||||
return frontFace switch
|
||||
{
|
||||
GAL.FrontFace.Clockwise => Silk.NET.Vulkan.FrontFace.CounterClockwise,
|
||||
GAL.FrontFace.CounterClockwise => Silk.NET.Vulkan.FrontFace.Clockwise,
|
||||
_ => LogInvalidAndReturn(frontFace, nameof(GAL.FrontFace), Silk.NET.Vulkan.FrontFace.Clockwise)
|
||||
GAL.FrontFace.Clockwise => FrontFace.CounterClockwise,
|
||||
GAL.FrontFace.CounterClockwise => 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
|
||||
{
|
||||
GAL.IndexType.UByte => Silk.NET.Vulkan.IndexType.Uint8Ext,
|
||||
GAL.IndexType.UShort => Silk.NET.Vulkan.IndexType.Uint16,
|
||||
GAL.IndexType.UInt => Silk.NET.Vulkan.IndexType.Uint32,
|
||||
_ => LogInvalidAndReturn(type, nameof(GAL.IndexType), Silk.NET.Vulkan.IndexType.Uint16)
|
||||
GAL.IndexType.UByte => IndexType.Uint8Ext,
|
||||
GAL.IndexType.UShort => IndexType.Uint16,
|
||||
GAL.IndexType.UInt => IndexType.Uint32,
|
||||
_ => LogInvalidAndReturn(type, nameof(GAL.IndexType), IndexType.Uint16),
|
||||
};
|
||||
}
|
||||
|
||||
@ -262,7 +270,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
MagFilter.Nearest => Filter.Nearest,
|
||||
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.NearestMipmapLinear => (Filter.Nearest, 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
|
||||
{
|
||||
GAL.PrimitiveTopology.Points => Silk.NET.Vulkan.PrimitiveTopology.PointList,
|
||||
GAL.PrimitiveTopology.Lines => Silk.NET.Vulkan.PrimitiveTopology.LineList,
|
||||
GAL.PrimitiveTopology.LineStrip => Silk.NET.Vulkan.PrimitiveTopology.LineStrip,
|
||||
GAL.PrimitiveTopology.Triangles => Silk.NET.Vulkan.PrimitiveTopology.TriangleList,
|
||||
GAL.PrimitiveTopology.TriangleStrip => Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip,
|
||||
GAL.PrimitiveTopology.TriangleFan => Silk.NET.Vulkan.PrimitiveTopology.TriangleFan,
|
||||
GAL.PrimitiveTopology.LinesAdjacency => Silk.NET.Vulkan.PrimitiveTopology.LineListWithAdjacency,
|
||||
GAL.PrimitiveTopology.LineStripAdjacency => Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency,
|
||||
GAL.PrimitiveTopology.TrianglesAdjacency => Silk.NET.Vulkan.PrimitiveTopology.TriangleListWithAdjacency,
|
||||
GAL.PrimitiveTopology.TriangleStripAdjacency => Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency,
|
||||
GAL.PrimitiveTopology.Patches => Silk.NET.Vulkan.PrimitiveTopology.PatchList,
|
||||
GAL.PrimitiveTopology.Polygon => Silk.NET.Vulkan.PrimitiveTopology.TriangleFan,
|
||||
GAL.PrimitiveTopology.Points => PrimitiveTopology.PointList,
|
||||
GAL.PrimitiveTopology.Lines => PrimitiveTopology.LineList,
|
||||
GAL.PrimitiveTopology.LineStrip => PrimitiveTopology.LineStrip,
|
||||
GAL.PrimitiveTopology.Triangles => PrimitiveTopology.TriangleList,
|
||||
GAL.PrimitiveTopology.TriangleStrip => PrimitiveTopology.TriangleStrip,
|
||||
GAL.PrimitiveTopology.TriangleFan => PrimitiveTopology.TriangleFan,
|
||||
GAL.PrimitiveTopology.LinesAdjacency => PrimitiveTopology.LineListWithAdjacency,
|
||||
GAL.PrimitiveTopology.LineStripAdjacency => PrimitiveTopology.LineStripWithAdjacency,
|
||||
GAL.PrimitiveTopology.TrianglesAdjacency => PrimitiveTopology.TriangleListWithAdjacency,
|
||||
GAL.PrimitiveTopology.TriangleStripAdjacency => PrimitiveTopology.TriangleStripWithAdjacency,
|
||||
GAL.PrimitiveTopology.Patches => PrimitiveTopology.PatchList,
|
||||
GAL.PrimitiveTopology.Polygon => PrimitiveTopology.TriangleFan,
|
||||
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."),
|
||||
_ => 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
|
||||
{
|
||||
GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => Silk.NET.Vulkan.StencilOp.Keep,
|
||||
GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => Silk.NET.Vulkan.StencilOp.Zero,
|
||||
GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => Silk.NET.Vulkan.StencilOp.Replace,
|
||||
GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => Silk.NET.Vulkan.StencilOp.IncrementAndClamp,
|
||||
GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => Silk.NET.Vulkan.StencilOp.DecrementAndClamp,
|
||||
GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => Silk.NET.Vulkan.StencilOp.Invert,
|
||||
GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => Silk.NET.Vulkan.StencilOp.IncrementAndWrap,
|
||||
GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => Silk.NET.Vulkan.StencilOp.DecrementAndWrap,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), Silk.NET.Vulkan.StencilOp.Keep)
|
||||
GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => StencilOp.Keep,
|
||||
GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => StencilOp.Zero,
|
||||
GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => StencilOp.Replace,
|
||||
GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => StencilOp.IncrementAndClamp,
|
||||
GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => StencilOp.DecrementAndClamp,
|
||||
GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => StencilOp.Invert,
|
||||
GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => StencilOp.IncrementAndWrap,
|
||||
GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => StencilOp.DecrementAndWrap,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), StencilOp.Keep),
|
||||
};
|
||||
}
|
||||
|
||||
@ -328,7 +336,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SwizzleComponent.Green => ComponentSwizzle.G,
|
||||
SwizzleComponent.Blue => ComponentSwizzle.B,
|
||||
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.CubemapArray => ImageType.Type2D,
|
||||
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.Cubemap => ImageViewType.TypeCube,
|
||||
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
|
||||
{
|
||||
GAL.Format.D16Unorm or GAL.Format.D32Float => ImageAspectFlags.DepthBit,
|
||||
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
GAL.Format.D24UnormS8Uint or
|
||||
GAL.Format.D32FloatS8Uint or
|
||||
GAL.Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
||||
_ => ImageAspectFlags.ColorBit
|
||||
Format.D16Unorm or Format.D32Float => ImageAspectFlags.DepthBit,
|
||||
Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
Format.D24UnormS8Uint or
|
||||
Format.D32FloatS8Uint or
|
||||
Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
||||
_ => ImageAspectFlags.ColorBit,
|
||||
};
|
||||
}
|
||||
|
||||
public static ImageAspectFlags ConvertAspectFlags(this GAL.Format format, DepthStencilMode depthStencilMode)
|
||||
public static ImageAspectFlags ConvertAspectFlags(this Format format, DepthStencilMode depthStencilMode)
|
||||
{
|
||||
return format switch
|
||||
{
|
||||
GAL.Format.D16Unorm or GAL.Format.D32Float => ImageAspectFlags.DepthBit,
|
||||
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
GAL.Format.D24UnormS8Uint or
|
||||
GAL.Format.D32FloatS8Uint or
|
||||
GAL.Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
|
||||
_ => ImageAspectFlags.ColorBit
|
||||
Format.D16Unorm or Format.D32Float => ImageAspectFlags.DepthBit,
|
||||
Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
Format.D24UnormS8Uint or
|
||||
Format.D32FloatS8Uint or
|
||||
Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
|
||||
_ => ImageAspectFlags.ColorBit,
|
||||
};
|
||||
}
|
||||
|
||||
@ -410,7 +418,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
LogicalOp.OrInverted => LogicOp.OrInverted,
|
||||
LogicalOp.Nand => LogicOp.Nand,
|
||||
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
|
||||
{
|
||||
BufferAccess.FlushPersistent => BufferAllocationType.HostMapped,
|
||||
_ => BufferAllocationType.Auto
|
||||
_ => BufferAllocationType.Auto,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_api = api;
|
||||
_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();
|
||||
@ -70,7 +70,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Span<Fence> fences = stackalloc Fence[]
|
||||
{
|
||||
_fence
|
||||
_fence,
|
||||
};
|
||||
|
||||
FenceHelper.WaitAllIndefinitely(_api, _device, fences);
|
||||
@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Span<Fence> fences = stackalloc Fence[]
|
||||
{
|
||||
_fence
|
||||
_fence,
|
||||
};
|
||||
|
||||
return FenceHelper.AllSignaled(_api, _device, fences);
|
||||
|
@ -2,6 +2,7 @@ using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
@ -19,15 +20,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_api = api;
|
||||
_physicalDevice = physicalDevice;
|
||||
|
||||
int totalFormats = Enum.GetNames(typeof(GAL.Format)).Length;
|
||||
int totalFormats = Enum.GetNames(typeof(Format)).Length;
|
||||
|
||||
_bufferTable = 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))
|
||||
{
|
||||
@ -38,9 +39,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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))
|
||||
{
|
||||
@ -51,7 +52,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool BufferFormatSupports(FormatFeatureFlags flags, GAL.Format format)
|
||||
public bool BufferFormatSupports(FormatFeatureFlags flags, Format format)
|
||||
{
|
||||
var formatFeatureFlags = _bufferTable[(int)format];
|
||||
|
||||
@ -72,7 +73,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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];
|
||||
|
||||
@ -86,7 +87,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return (formatFeatureFlags & flags) == flags;
|
||||
}
|
||||
|
||||
public VkFormat ConvertToVkFormat(GAL.Format srcFormat)
|
||||
public VkFormat ConvertToVkFormat(Format srcFormat)
|
||||
{
|
||||
var format = FormatTable.GetFormat(srcFormat);
|
||||
|
||||
@ -115,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
format = VkFormat.D32SfloatS8Uint;
|
||||
}
|
||||
else if (srcFormat == GAL.Format.R4G4B4A4Unorm)
|
||||
else if (srcFormat == Format.R4G4B4A4Unorm)
|
||||
{
|
||||
format = VkFormat.R4G4B4A4UnormPack16;
|
||||
}
|
||||
@ -128,7 +129,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return format;
|
||||
}
|
||||
|
||||
public VkFormat ConvertToVertexVkFormat(GAL.Format srcFormat)
|
||||
public VkFormat ConvertToVertexVkFormat(Format 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?
|
||||
switch (srcFormat)
|
||||
{
|
||||
case GAL.Format.R16G16B16Float:
|
||||
case Format.R16G16B16Float:
|
||||
format = VkFormat.R16G16B16A16Sfloat;
|
||||
break;
|
||||
case GAL.Format.R16G16B16Sint:
|
||||
case Format.R16G16B16Sint:
|
||||
format = VkFormat.R16G16B16A16Sint;
|
||||
break;
|
||||
case GAL.Format.R16G16B16Uint:
|
||||
case Format.R16G16B16Uint:
|
||||
format = VkFormat.R16G16B16A16Uint;
|
||||
break;
|
||||
default:
|
||||
@ -156,16 +157,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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 ||
|
||||
format == GAL.Format.R16G16B16Sint ||
|
||||
format == GAL.Format.R16G16B16Uint;
|
||||
return format == Format.R16G16B16Float ||
|
||||
format == Format.R16G16B16Sint ||
|
||||
format == Format.R16G16B16Uint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
_table = new VkFormat[Enum.GetNames(typeof(Format)).Length];
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
Add(Format.R8Unorm, VkFormat.R8Unorm);
|
||||
Add(Format.R8Snorm, VkFormat.R8SNorm);
|
||||
Add(Format.R8Uint, VkFormat.R8Uint);
|
||||
@ -157,6 +158,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Add(Format.A1B5G5R5Unorm, VkFormat.R5G5B5A1UnormPack16);
|
||||
Add(Format.B8G8R8A8Unorm, VkFormat.B8G8R8A8Unorm);
|
||||
Add(Format.B8G8R8A8Srgb, VkFormat.B8G8R8A8Srgb);
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
private static void Add(Format format, VkFormat vkFormat)
|
||||
@ -175,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Format.R8G8B8A8Srgb => Format.R8G8B8A8Unorm,
|
||||
Format.B8G8R8A8Srgb => Format.B8G8R8A8Unorm,
|
||||
_ => format
|
||||
_ => format,
|
||||
};
|
||||
}
|
||||
|
||||
@ -280,121 +282,61 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public static VkFormat DropLastComponent(VkFormat format)
|
||||
{
|
||||
switch (format)
|
||||
return format switch
|
||||
{
|
||||
case VkFormat.R8G8Unorm:
|
||||
return VkFormat.R8Unorm;
|
||||
case VkFormat.R8G8SNorm:
|
||||
return VkFormat.R8SNorm;
|
||||
case VkFormat.R8G8Uint:
|
||||
return VkFormat.R8Uint;
|
||||
case VkFormat.R8G8Sint:
|
||||
return VkFormat.R8Sint;
|
||||
case VkFormat.R8G8Uscaled:
|
||||
return VkFormat.R8Uscaled;
|
||||
case VkFormat.R8G8Sscaled:
|
||||
return VkFormat.R8Sscaled;
|
||||
|
||||
case VkFormat.R8G8B8Unorm:
|
||||
return VkFormat.R8G8Unorm;
|
||||
case VkFormat.R8G8B8SNorm:
|
||||
return VkFormat.R8G8SNorm;
|
||||
case VkFormat.R8G8B8Uint:
|
||||
return VkFormat.R8G8Uint;
|
||||
case VkFormat.R8G8B8Sint:
|
||||
return VkFormat.R8G8Sint;
|
||||
case VkFormat.R8G8B8Uscaled:
|
||||
return VkFormat.R8G8Uscaled;
|
||||
case VkFormat.R8G8B8Sscaled:
|
||||
return VkFormat.R8G8Sscaled;
|
||||
|
||||
case VkFormat.R8G8B8A8Unorm:
|
||||
return VkFormat.R8G8B8Unorm;
|
||||
case VkFormat.R8G8B8A8SNorm:
|
||||
return VkFormat.R8G8B8SNorm;
|
||||
case VkFormat.R8G8B8A8Uint:
|
||||
return VkFormat.R8G8B8Uint;
|
||||
case VkFormat.R8G8B8A8Sint:
|
||||
return VkFormat.R8G8B8Sint;
|
||||
case VkFormat.R8G8B8A8Srgb:
|
||||
return VkFormat.R8G8B8Srgb;
|
||||
case VkFormat.R8G8B8A8Uscaled:
|
||||
return VkFormat.R8G8B8Uscaled;
|
||||
case VkFormat.R8G8B8A8Sscaled:
|
||||
return VkFormat.R8G8B8Sscaled;
|
||||
case VkFormat.B8G8R8A8Unorm:
|
||||
return VkFormat.B8G8R8Unorm;
|
||||
case VkFormat.B8G8R8A8Srgb:
|
||||
return VkFormat.B8G8R8Srgb;
|
||||
|
||||
case VkFormat.R16G16Sfloat:
|
||||
return VkFormat.R16Sfloat;
|
||||
case VkFormat.R16G16Unorm:
|
||||
return VkFormat.R16Unorm;
|
||||
case VkFormat.R16G16SNorm:
|
||||
return VkFormat.R16SNorm;
|
||||
case VkFormat.R16G16Uint:
|
||||
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;
|
||||
VkFormat.R8G8Unorm => VkFormat.R8Unorm,
|
||||
VkFormat.R8G8SNorm => VkFormat.R8SNorm,
|
||||
VkFormat.R8G8Uint => VkFormat.R8Uint,
|
||||
VkFormat.R8G8Sint => VkFormat.R8Sint,
|
||||
VkFormat.R8G8Uscaled => VkFormat.R8Uscaled,
|
||||
VkFormat.R8G8Sscaled => VkFormat.R8Sscaled,
|
||||
VkFormat.R8G8B8Unorm => VkFormat.R8G8Unorm,
|
||||
VkFormat.R8G8B8SNorm => VkFormat.R8G8SNorm,
|
||||
VkFormat.R8G8B8Uint => VkFormat.R8G8Uint,
|
||||
VkFormat.R8G8B8Sint => VkFormat.R8G8Sint,
|
||||
VkFormat.R8G8B8Uscaled => VkFormat.R8G8Uscaled,
|
||||
VkFormat.R8G8B8Sscaled => VkFormat.R8G8Sscaled,
|
||||
VkFormat.R8G8B8A8Unorm => VkFormat.R8G8B8Unorm,
|
||||
VkFormat.R8G8B8A8SNorm => VkFormat.R8G8B8SNorm,
|
||||
VkFormat.R8G8B8A8Uint => VkFormat.R8G8B8Uint,
|
||||
VkFormat.R8G8B8A8Sint => VkFormat.R8G8B8Sint,
|
||||
VkFormat.R8G8B8A8Srgb => VkFormat.R8G8B8Srgb,
|
||||
VkFormat.R8G8B8A8Uscaled => VkFormat.R8G8B8Uscaled,
|
||||
VkFormat.R8G8B8A8Sscaled => VkFormat.R8G8B8Sscaled,
|
||||
VkFormat.B8G8R8A8Unorm => VkFormat.B8G8R8Unorm,
|
||||
VkFormat.B8G8R8A8Srgb => VkFormat.B8G8R8Srgb,
|
||||
VkFormat.R16G16Sfloat => VkFormat.R16Sfloat,
|
||||
VkFormat.R16G16Unorm => VkFormat.R16Unorm,
|
||||
VkFormat.R16G16SNorm => VkFormat.R16SNorm,
|
||||
VkFormat.R16G16Uint => VkFormat.R16Uint,
|
||||
VkFormat.R16G16Sint => VkFormat.R16Sint,
|
||||
VkFormat.R16G16Uscaled => VkFormat.R16Uscaled,
|
||||
VkFormat.R16G16Sscaled => VkFormat.R16Sscaled,
|
||||
VkFormat.R16G16B16Sfloat => VkFormat.R16G16Sfloat,
|
||||
VkFormat.R16G16B16Unorm => VkFormat.R16G16Unorm,
|
||||
VkFormat.R16G16B16SNorm => VkFormat.R16G16SNorm,
|
||||
VkFormat.R16G16B16Uint => VkFormat.R16G16Uint,
|
||||
VkFormat.R16G16B16Sint => VkFormat.R16G16Sint,
|
||||
VkFormat.R16G16B16Uscaled => VkFormat.R16G16Uscaled,
|
||||
VkFormat.R16G16B16Sscaled => VkFormat.R16G16Sscaled,
|
||||
VkFormat.R16G16B16A16Sfloat => VkFormat.R16G16B16Sfloat,
|
||||
VkFormat.R16G16B16A16Unorm => VkFormat.R16G16B16Unorm,
|
||||
VkFormat.R16G16B16A16SNorm => VkFormat.R16G16B16SNorm,
|
||||
VkFormat.R16G16B16A16Uint => VkFormat.R16G16B16Uint,
|
||||
VkFormat.R16G16B16A16Sint => VkFormat.R16G16B16Sint,
|
||||
VkFormat.R16G16B16A16Uscaled => VkFormat.R16G16B16Uscaled,
|
||||
VkFormat.R16G16B16A16Sscaled => VkFormat.R16G16B16Sscaled,
|
||||
VkFormat.R32G32Sfloat => VkFormat.R32Sfloat,
|
||||
VkFormat.R32G32Uint => VkFormat.R32Uint,
|
||||
VkFormat.R32G32Sint => VkFormat.R32Sint,
|
||||
VkFormat.R32G32B32Sfloat => VkFormat.R32G32Sfloat,
|
||||
VkFormat.R32G32B32Uint => VkFormat.R32G32Uint,
|
||||
VkFormat.R32G32B32Sint => VkFormat.R32G32Sint,
|
||||
VkFormat.R32G32B32A32Sfloat => VkFormat.R32G32B32Sfloat,
|
||||
VkFormat.R32G32B32A32Uint => VkFormat.R32G32B32Uint,
|
||||
VkFormat.R32G32B32A32Sint => VkFormat.R32G32B32Sint,
|
||||
_ => format,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Auto<DisposableImageView>[] _attachments;
|
||||
private readonly TextureView[] _colors;
|
||||
private readonly TextureView _depthStencil;
|
||||
private uint _validColorAttachments;
|
||||
private readonly uint _validColorAttachments;
|
||||
|
||||
public uint Width { get; }
|
||||
public uint Height { get; }
|
||||
@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public uint AttachmentIntegerFormatMask { 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 int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
||||
|
||||
@ -158,7 +158,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
return ComponentType.SignedInteger;
|
||||
}
|
||||
else if (format.IsUint())
|
||||
|
||||
if (format.IsUint())
|
||||
{
|
||||
return ComponentType.UnsignedInteger;
|
||||
}
|
||||
@ -196,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
attachments[i] = _attachments[i].Get(cbs).Value;
|
||||
}
|
||||
|
||||
var framebufferCreateInfo = new FramebufferCreateInfo()
|
||||
var framebufferCreateInfo = new FramebufferCreateInfo
|
||||
{
|
||||
SType = StructureType.FramebufferCreateInfo,
|
||||
RenderPass = renderPass.Get(cbs).Value,
|
||||
@ -204,7 +205,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PAttachments = attachments,
|
||||
Width = Width,
|
||||
Height = Height,
|
||||
Layers = Layers
|
||||
Layers = Layers,
|
||||
};
|
||||
|
||||
api.CreateFramebuffer(_device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
||||
|
@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
NoTriangleFans = 1,
|
||||
NoPointMode = 1 << 1,
|
||||
No3DImageView = 1 << 2,
|
||||
NoLodBias = 1 << 3
|
||||
NoLodBias = 1 << 3,
|
||||
}
|
||||
|
||||
readonly struct HardwareCapabilities
|
||||
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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 TotalBucketsMask = TotalBuckets - 1;
|
||||
@ -16,13 +16,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private struct Entry
|
||||
{
|
||||
public int Hash;
|
||||
public K Key;
|
||||
public V Value;
|
||||
public TKey Key;
|
||||
public TValue Value;
|
||||
}
|
||||
|
||||
private readonly Entry[][] _hashTable = new Entry[TotalBuckets][];
|
||||
|
||||
public IEnumerable<K> Keys
|
||||
public IEnumerable<TKey> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<V> Values
|
||||
public IEnumerable<TValue> Values
|
||||
{
|
||||
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(),
|
||||
Key = key,
|
||||
Value = value
|
||||
Value = value,
|
||||
};
|
||||
|
||||
int hashCode = key.GetHashCode();
|
||||
@ -79,14 +79,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
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();
|
||||
|
||||
|
@ -6,6 +6,12 @@ using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
@ -14,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Float,
|
||||
SignedInteger,
|
||||
UnsignedInteger
|
||||
UnsignedInteger,
|
||||
}
|
||||
|
||||
class HelperShader : IDisposable
|
||||
@ -52,8 +58,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_pipeline = new PipelineHelperShader(gd, device);
|
||||
_pipeline.Initialize();
|
||||
|
||||
_samplerLinear = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
_samplerNearest = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
||||
_samplerLinear = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
_samplerNearest = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
||||
|
||||
var blitResourceLayout = new ResourceLayoutBuilder()
|
||||
.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)) });
|
||||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||
|
||||
var rect = new Rectangle<float>(
|
||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||
@ -424,7 +430,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@ -440,7 +446,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (dstIsDepthOrStencil)
|
||||
{
|
||||
_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())
|
||||
{
|
||||
@ -465,12 +471,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.Draw(4, 1, 0, 0);
|
||||
|
||||
if (dstIsDepthOrStencil)
|
||||
{
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||
}
|
||||
|
||||
_pipeline.Finish(gd, cbs);
|
||||
@ -517,7 +523,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_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>(
|
||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||
@ -525,7 +531,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@ -541,7 +547,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat);
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
|
||||
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
||||
|
||||
@ -606,7 +612,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (isDepth)
|
||||
{
|
||||
_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
|
||||
{
|
||||
@ -618,7 +624,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (isDepth)
|
||||
{
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -630,17 +636,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
return new StencilTestDescriptor(
|
||||
enabled,
|
||||
GAL.CompareOp.Always,
|
||||
GAL.StencilOp.Replace,
|
||||
GAL.StencilOp.Replace,
|
||||
GAL.StencilOp.Replace,
|
||||
CompareOp.Always,
|
||||
StencilOp.Replace,
|
||||
StencilOp.Replace,
|
||||
StencilOp.Replace,
|
||||
0,
|
||||
0xff,
|
||||
0xff,
|
||||
GAL.CompareOp.Always,
|
||||
GAL.StencilOp.Replace,
|
||||
GAL.StencilOp.Replace,
|
||||
GAL.StencilOp.Replace,
|
||||
CompareOp.Always,
|
||||
StencilOp.Replace,
|
||||
StencilOp.Replace,
|
||||
StencilOp.Replace,
|
||||
0,
|
||||
0xff,
|
||||
0xff);
|
||||
@ -667,13 +673,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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)) });
|
||||
|
||||
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),
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@ -703,10 +709,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetProgram(program);
|
||||
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat);
|
||||
_pipeline.SetRenderTargetColorMasks(new uint[] { componentMask });
|
||||
_pipeline.SetRenderTargetColorMasks(new[] { componentMask });
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.Draw(4, 1, 0, 0);
|
||||
_pipeline.Finish();
|
||||
|
||||
@ -748,7 +754,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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>(
|
||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||
@ -756,7 +762,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@ -769,13 +775,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
pipeline.SetProgram(_programColorBlit);
|
||||
pipeline.SetViewports(viewports, false);
|
||||
pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
pipeline.Draw(4, 1, 0, 0);
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1093,11 +1099,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
// 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);
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@ -1112,7 +1118,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
|
||||
for (int z = 0; z < depth; z++)
|
||||
{
|
||||
@ -1120,7 +1126,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||
|
||||
_pipeline.SetRenderTarget(
|
||||
((TextureView)dstView).GetImageViewForAttachment(),
|
||||
dstView.GetImageViewForAttachment(),
|
||||
(uint)dst.Width,
|
||||
(uint)dst.Height,
|
||||
true,
|
||||
@ -1225,11 +1231,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_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);
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@ -1245,7 +1251,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_pipeline.SetRenderTargetColorMasks(new uint[] { 0xf });
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
|
||||
_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);
|
||||
|
||||
_pipeline.SetRenderTarget(
|
||||
((TextureView)dstView).GetImageViewForAttachment(),
|
||||
dstView.GetImageViewForAttachment(),
|
||||
(uint)dst.Width,
|
||||
(uint)dst.Height,
|
||||
(uint)samples,
|
||||
@ -1291,7 +1297,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, srcView, null);
|
||||
_pipeline.SetRenderTarget(
|
||||
((TextureView)dstView).GetView(format).GetImageViewForAttachment(),
|
||||
dstView.GetView(format).GetImageViewForAttachment(),
|
||||
(uint)dst.Width,
|
||||
(uint)dst.Height,
|
||||
(uint)samples,
|
||||
@ -1365,7 +1371,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (isDepth)
|
||||
{
|
||||
_pipeline.SetProgram(fromMS ? _programDepthDrawToNonMs : _programDepthDrawToMs);
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1377,7 +1383,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (isDepth)
|
||||
{
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1420,7 +1426,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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))
|
||||
{
|
||||
@ -1431,7 +1437,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Target.Texture1DArray => Target.Texture1D,
|
||||
Target.Texture2DMultisampleArray => Target.Texture2DMultisample,
|
||||
_ => Target.Texture2D
|
||||
_ => Target.Texture2D,
|
||||
};
|
||||
|
||||
var info = new TextureCreateInfo(
|
||||
@ -1454,55 +1460,55 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return from.CreateViewImpl(info, layer, level);
|
||||
}
|
||||
|
||||
private static GAL.Format GetFormat(int bytesPerPixel)
|
||||
private static Format GetFormat(int bytesPerPixel)
|
||||
{
|
||||
return bytesPerPixel switch
|
||||
{
|
||||
1 => GAL.Format.R8Uint,
|
||||
2 => GAL.Format.R16Uint,
|
||||
4 => GAL.Format.R32Uint,
|
||||
8 => GAL.Format.R32G32Uint,
|
||||
16 => GAL.Format.R32G32B32A32Uint,
|
||||
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}.")
|
||||
1 => Format.R8Uint,
|
||||
2 => Format.R16Uint,
|
||||
4 => Format.R32Uint,
|
||||
8 => Format.R32G32Uint,
|
||||
16 => Format.R32G32B32A32Uint,
|
||||
_ => 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)
|
||||
{
|
||||
return componentsCount switch
|
||||
{
|
||||
1 => GAL.Format.R8Uint,
|
||||
2 => GAL.Format.R8G8Uint,
|
||||
4 => GAL.Format.R8G8B8A8Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
||||
1 => Format.R8Uint,
|
||||
2 => Format.R8G8Uint,
|
||||
4 => Format.R8G8B8A8Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||
};
|
||||
}
|
||||
else if (componentSize == 2)
|
||||
|
||||
if (componentSize == 2)
|
||||
{
|
||||
return componentsCount switch
|
||||
{
|
||||
1 => GAL.Format.R16Uint,
|
||||
2 => GAL.Format.R16G16Uint,
|
||||
4 => GAL.Format.R16G16B16A16Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
||||
1 => Format.R16Uint,
|
||||
2 => Format.R16G16Uint,
|
||||
4 => Format.R16G16B16A16Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||
};
|
||||
}
|
||||
else if (componentSize == 4)
|
||||
|
||||
if (componentSize == 4)
|
||||
{
|
||||
return componentsCount switch
|
||||
{
|
||||
1 => GAL.Format.R32Uint,
|
||||
2 => GAL.Format.R32G32Uint,
|
||||
4 => GAL.Format.R32G32B32A32Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
||||
1 => Format.R32Uint,
|
||||
2 => Format.R32G32Uint,
|
||||
4 => Format.R32G32B32A32Uint,
|
||||
_ => 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(
|
||||
@ -1524,7 +1530,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
// TODO: Support conversion with primitive restart enabled.
|
||||
|
||||
BufferRange drawCountBufferAligned = new BufferRange(
|
||||
BufferRange drawCountBufferAligned = new(
|
||||
drawCountBuffer.Handle,
|
||||
drawCountBuffer.Offset & ~(UniformBufferAlignment - 1),
|
||||
UniformBufferAlignment);
|
||||
@ -1562,7 +1568,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
shaderParams[22] = indirectDataStride / 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 patternBufferAuto = patternBuffer.GetBuffer();
|
||||
|
@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal class HostMemoryAllocator
|
||||
{
|
||||
private struct HostMemoryAllocation
|
||||
private readonly struct HostMemoryAllocation
|
||||
{
|
||||
public readonly Auto<MemoryAllocation> Allocation;
|
||||
public readonly IntPtr Pointer;
|
||||
@ -33,8 +33,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Device _device;
|
||||
private readonly object _lock = new();
|
||||
|
||||
private List<HostMemoryAllocation> _allocations;
|
||||
private IntervalTree<ulong, HostMemoryAllocation> _allocationTree;
|
||||
private readonly List<HostMemoryAllocation> _allocations;
|
||||
private readonly IntervalTree<ulong, HostMemoryAllocation> _allocationTree;
|
||||
|
||||
public HostMemoryAllocator(MemoryAllocator allocator, Vk api, ExtExternalMemoryHost hostMemoryApi, Device device)
|
||||
{
|
||||
@ -100,19 +100,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return false;
|
||||
}
|
||||
|
||||
ImportMemoryHostPointerInfoEXT importInfo = new ImportMemoryHostPointerInfoEXT()
|
||||
ImportMemoryHostPointerInfoEXT importInfo = new()
|
||||
{
|
||||
SType = StructureType.ImportMemoryHostPointerInfoExt,
|
||||
HandleType = ExternalMemoryHandleTypeFlags.HostAllocationBitExt,
|
||||
PHostPointer = (void*)pageAlignedPointer
|
||||
PHostPointer = (void*)pageAlignedPointer,
|
||||
};
|
||||
|
||||
var memoryAllocateInfo = new MemoryAllocateInfo()
|
||||
var memoryAllocateInfo = new MemoryAllocateInfo
|
||||
{
|
||||
SType = StructureType.MemoryAllocateInfo,
|
||||
AllocationSize = pageAlignedSize,
|
||||
MemoryTypeIndex = (uint)memoryTypeIndex,
|
||||
PNext = &importInfo
|
||||
PNext = &importInfo,
|
||||
};
|
||||
|
||||
Result result = _api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory);
|
||||
|
@ -85,11 +85,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
value = _list[id];
|
||||
return value != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
@ -120,4 +118,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public int IndexStride { get; }
|
||||
public bool RepeatStart { get; }
|
||||
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
private int _currentSize;
|
||||
private BufferHandle _repeatingBuffer;
|
||||
|
||||
|
@ -1,19 +1,20 @@
|
||||
using Silk.NET.Vulkan;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using IndexType = Silk.NET.Vulkan.IndexType;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
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 _size;
|
||||
private readonly IndexType _type;
|
||||
|
||||
private readonly GAL.BufferHandle _handle;
|
||||
private readonly BufferHandle _handle;
|
||||
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;
|
||||
_offset = offset;
|
||||
@ -22,7 +23,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = null;
|
||||
}
|
||||
|
||||
public IndexBufferState(GAL.BufferHandle handle, int offset, int size)
|
||||
public IndexBufferState(BufferHandle handle, int offset, int size)
|
||||
{
|
||||
_handle = handle;
|
||||
_offset = offset;
|
||||
@ -97,8 +98,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public Auto<DisposableBuffer> BindConvertedIndexBufferIndirect(
|
||||
VulkanRenderer gd,
|
||||
CommandBufferScoped cbs,
|
||||
GAL.BufferRange indirectBuffer,
|
||||
GAL.BufferRange drawCountBuffer,
|
||||
BufferRange indirectBuffer,
|
||||
BufferRange drawCountBuffer,
|
||||
IndexBufferPattern pattern,
|
||||
bool hasDrawCount,
|
||||
int maxDrawCount,
|
||||
@ -110,7 +111,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
(var indexBufferAuto, var indirectBufferAuto) = gd.BufferManager.GetBufferTopologyConversionIndirect(
|
||||
gd,
|
||||
cbs,
|
||||
new GAL.BufferRange(_handle, _offset, _size),
|
||||
new BufferRange(_handle, _offset, _size),
|
||||
indirectBuffer,
|
||||
drawCountBuffer,
|
||||
pattern,
|
||||
@ -132,7 +133,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return indirectBufferAuto;
|
||||
}
|
||||
|
||||
private int GetIndexSize()
|
||||
private readonly int GetIndexSize()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly HostMemoryAllocator _hostMemory;
|
||||
|
||||
public DeviceMemory Memory { get; }
|
||||
public IntPtr HostPointer { get;}
|
||||
public IntPtr HostPointer { get; }
|
||||
public ulong Offset { get; }
|
||||
public ulong Size { get; }
|
||||
|
||||
|
@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
class MemoryAllocator : IDisposable
|
||||
{
|
||||
private ulong MaxDeviceMemoryUsageEstimate = 16UL * 1024 * 1024 * 1024;
|
||||
private const ulong MaxDeviceMemoryUsageEstimate = 16UL * 1024 * 1024 * 1024;
|
||||
|
||||
private readonly Vk _api;
|
||||
private readonly VulkanPhysicalDevice _physicalDevice;
|
||||
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_physicalDevice = physicalDevice;
|
||||
_device = device;
|
||||
_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(
|
||||
|
@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Size = size;
|
||||
_freeRanges = new List<Range>
|
||||
{
|
||||
new Range(0, size)
|
||||
new Range(0, size),
|
||||
};
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
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 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,
|
||||
AllocationSize = blockAlignedSize,
|
||||
MemoryTypeIndex = (uint)MemoryTypeIndex
|
||||
MemoryTypeIndex = (uint)MemoryTypeIndex,
|
||||
};
|
||||
|
||||
_api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory).ThrowOnError();
|
||||
@ -213,12 +213,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (map)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
void* pointer = null;
|
||||
_api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError();
|
||||
hostPointer = (IntPtr)pointer;
|
||||
}
|
||||
void* pointer = null;
|
||||
_api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError();
|
||||
hostPointer = (IntPtr)pointer;
|
||||
}
|
||||
|
||||
var newBlock = new Block(deviceMemory, hostPointer, blockAlignedSize);
|
||||
@ -238,10 +235,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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);
|
||||
|
||||
@ -271,7 +268,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_blocks.Insert(index, block);
|
||||
}
|
||||
|
||||
public unsafe void Dispose()
|
||||
public void Dispose()
|
||||
{
|
||||
for (int i = 0; i < _blocks.Count; i++)
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
Error = 1,
|
||||
Warning = 2,
|
||||
Info = 3,
|
||||
Debug = 4
|
||||
Debug = 4,
|
||||
}
|
||||
|
||||
enum MVKConfigTraceVulkanCalls
|
||||
@ -17,14 +17,14 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
None = 0,
|
||||
Enter = 1,
|
||||
EnterExit = 2,
|
||||
Duration = 3
|
||||
Duration = 3,
|
||||
}
|
||||
|
||||
enum MVKConfigAutoGPUCaptureScope
|
||||
{
|
||||
None = 0,
|
||||
Device = 1,
|
||||
Frame = 2
|
||||
Frame = 2,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
All = 0x00000001,
|
||||
MoltenVK = 0x00000002,
|
||||
WSI = 0x00000004,
|
||||
Portability = 0x00000008
|
||||
Portability = 0x00000008,
|
||||
}
|
||||
|
||||
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 = 2,
|
||||
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
|
||||
@ -60,7 +60,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
}
|
||||
|
||||
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)]
|
||||
|
@ -30,4 +30,4 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
vkSetMoltenVKConfigurationMVK(IntPtr.Zero, config, configSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
/// </summary>
|
||||
class MultiFenceHolder
|
||||
{
|
||||
private static int BufferUsageTrackingGranularity = 4096;
|
||||
private static readonly int _bufferUsageTrackingGranularity = 4096;
|
||||
|
||||
private readonly FenceHolder[] _fences;
|
||||
private BufferUsageBitmap _bufferUsageBitmap;
|
||||
private readonly BufferUsageBitmap _bufferUsageBitmap;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the multiple fence holder.
|
||||
@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public MultiFenceHolder(int size)
|
||||
{
|
||||
_fences = new FenceHolder[CommandBufferPool.MaxCommandBuffers];
|
||||
_bufferUsageBitmap = new BufferUsageBitmap(size, BufferUsageTrackingGranularity);
|
||||
_bufferUsageBitmap = new BufferUsageBitmap(size, _bufferUsageTrackingGranularity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -189,11 +189,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (hasTimeout)
|
||||
{
|
||||
signaled = FenceHelper.AllSignaled(api, device, fences.Slice(0, fenceCount), timeout);
|
||||
signaled = FenceHelper.AllSignaled(api, device, fences[..fenceCount], timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
FenceHelper.WaitAllIndefinitely(api, device, fences.Slice(0, fenceCount));
|
||||
FenceHelper.WaitAllIndefinitely(api, device, fences[..fenceCount]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < fenceCount; i++)
|
||||
|
@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal class PersistentFlushBuffer : IDisposable
|
||||
{
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
|
||||
private BufferHolder _flushStorage;
|
||||
|
||||
@ -19,10 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (flushStorage == null || size > _flushStorage.Size)
|
||||
{
|
||||
if (flushStorage != null)
|
||||
{
|
||||
flushStorage.Dispose();
|
||||
}
|
||||
flushStorage?.Dispose();
|
||||
|
||||
flushStorage = _gd.BufferManager.Create(_gd, size);
|
||||
_flushStorage = flushStorage;
|
||||
@ -59,7 +57,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size)
|
||||
{
|
||||
GAL.TextureCreateInfo info = view.Info;
|
||||
TextureCreateInfo info = view.Info;
|
||||
|
||||
var flushStorage = ResizeIfNeeded(size);
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
@ -7,6 +6,13 @@ using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
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
|
||||
{
|
||||
@ -28,7 +34,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
protected PipelineDynamicState DynamicState;
|
||||
private PipelineState _newState;
|
||||
private bool _stateDirty;
|
||||
private GAL.PrimitiveTopology _topology;
|
||||
private PrimitiveTopology _topology;
|
||||
|
||||
private ulong _currentPipelineHandle;
|
||||
|
||||
@ -44,7 +50,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private ShaderCollection _program;
|
||||
|
||||
private Vector4<float>[] _renderScale = new Vector4<float>[73];
|
||||
private readonly Vector4<float>[] _renderScale = new Vector4<float>[73];
|
||||
private int _fragmentScaleCount;
|
||||
|
||||
protected FramebufferParams FramebufferParams;
|
||||
@ -78,7 +84,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private bool _tfEnabled;
|
||||
private bool _tfActive;
|
||||
|
||||
private PipelineColorBlendAttachmentState[] _storedBlend;
|
||||
private readonly PipelineColorBlendAttachmentState[] _storedBlend;
|
||||
|
||||
private ulong _drawCountSinceBarrier;
|
||||
public ulong DrawCount { get; private set; }
|
||||
@ -91,9 +97,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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();
|
||||
@ -108,7 +114,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
using var emptyVb = gd.BufferManager.Create(gd, 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);
|
||||
|
||||
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,
|
||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
};
|
||||
|
||||
Gd.Api.CmdPipelineBarrier(
|
||||
@ -168,11 +174,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void ComputeBarrier()
|
||||
{
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
};
|
||||
|
||||
Gd.Api.CmdPipelineBarrier(
|
||||
@ -188,7 +194,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ReadOnlySpan<ImageMemoryBarrier>.Empty);
|
||||
}
|
||||
|
||||
public void BeginTransformFeedback(GAL.PrimitiveTopology topology)
|
||||
public void BeginTransformFeedback(PrimitiveTopology topology)
|
||||
{
|
||||
_tfEnabled = true;
|
||||
}
|
||||
@ -281,11 +287,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public unsafe void CommandBufferBarrier()
|
||||
{
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = BufferHolder.DefaultAccessFlags,
|
||||
DstAccessMask = AccessFlags.IndirectCommandReadBit
|
||||
DstAccessMask = AccessFlags.IndirectCommandReadBit,
|
||||
};
|
||||
|
||||
Gd.Api.CmdPipelineBarrier(
|
||||
@ -374,10 +380,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
IndexBufferPattern pattern = _topology switch
|
||||
{
|
||||
GAL.PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||
GAL.PrimitiveTopology.TriangleFan or
|
||||
GAL.PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}")
|
||||
PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||
PrimitiveTopology.TriangleFan or
|
||||
PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}"),
|
||||
};
|
||||
|
||||
BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount);
|
||||
@ -406,10 +412,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
pattern = _topology switch
|
||||
{
|
||||
GAL.PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||
GAL.PrimitiveTopology.TriangleFan or
|
||||
GAL.PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}")
|
||||
PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||
PrimitiveTopology.TriangleFan or
|
||||
PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}"),
|
||||
};
|
||||
}
|
||||
|
||||
@ -718,7 +724,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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.
|
||||
// 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();
|
||||
}
|
||||
|
||||
public void SetFrontFace(GAL.FrontFace frontFace)
|
||||
public void SetFrontFace(FrontFace frontFace)
|
||||
{
|
||||
_newState.FrontFace = frontFace.Convert();
|
||||
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);
|
||||
}
|
||||
@ -863,7 +869,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_descriptorSetUpdater.SetImage(binding, image);
|
||||
}
|
||||
|
||||
public void SetIndexBuffer(BufferRange buffer, GAL.IndexType type)
|
||||
public void SetIndexBuffer(BufferRange buffer, IndexType type)
|
||||
{
|
||||
if (buffer.Handle != BufferHandle.Null)
|
||||
{
|
||||
@ -897,12 +903,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SignalStateChange();
|
||||
}
|
||||
|
||||
public void SetOrigin(Origin origin)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
|
||||
public unsafe void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
||||
public void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
||||
{
|
||||
_newState.PatchControlPoints = (uint)vertices;
|
||||
SignalStateChange();
|
||||
@ -910,15 +911,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// 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)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
|
||||
public void SetPolygonMode(GAL.PolygonMode frontMode, GAL.PolygonMode backMode)
|
||||
public void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
#pragma warning restore CA1822
|
||||
|
||||
public void SetPrimitiveRestart(bool enable, int index)
|
||||
{
|
||||
@ -927,7 +930,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SignalStateChange();
|
||||
}
|
||||
|
||||
public void SetPrimitiveTopology(GAL.PrimitiveTopology topology)
|
||||
public void SetPrimitiveTopology(PrimitiveTopology topology)
|
||||
{
|
||||
_topology = topology;
|
||||
|
||||
@ -950,7 +953,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_newState.PipelineLayout = internalProgram.PipelineLayout;
|
||||
_newState.StagesCount = (uint)stages.Length;
|
||||
|
||||
stages.CopyTo(_newState.Stages.AsSpan().Slice(0, stages.Length));
|
||||
stages.CopyTo(_newState.Stages.AsSpan()[..stages.Length]);
|
||||
|
||||
SignalStateChange();
|
||||
|
||||
@ -1149,10 +1152,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_descriptorSetUpdater.SetUniformBuffers(CommandBuffer, buffers);
|
||||
}
|
||||
|
||||
#pragma warning disable CA1822 // Mark member as static
|
||||
public void SetUserClipDistance(int index, bool enableClip)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
#pragma warning restore CA1822
|
||||
|
||||
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
||||
{
|
||||
@ -1298,7 +1303,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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 count = Math.Min(maxViewports, viewports.Length);
|
||||
@ -1332,7 +1337,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
X = scale * 2f / viewports[0].Region.Width,
|
||||
Y = scale * 2f / viewports[0].Region.Height,
|
||||
Z = 1,
|
||||
W = disableTransformF
|
||||
W = disableTransformF,
|
||||
});
|
||||
}
|
||||
|
||||
@ -1361,11 +1366,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public unsafe void TextureBarrier()
|
||||
{
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
};
|
||||
|
||||
Gd.Api.CmdPipelineBarrier(
|
||||
@ -1433,7 +1438,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// Just try to remove duplicate attachments.
|
||||
// Save a copy of the array to rebind when mask changes.
|
||||
|
||||
void maskOut()
|
||||
void MaskOut()
|
||||
{
|
||||
if (!_framebufferUsingColorWriteMask)
|
||||
{
|
||||
@ -1467,12 +1472,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (vkBlend.ColorWriteMask == 0)
|
||||
{
|
||||
colors[i] = null;
|
||||
maskOut();
|
||||
MaskOut();
|
||||
}
|
||||
else if (vkBlend2.ColorWriteMask == 0)
|
||||
{
|
||||
colors[j] = null;
|
||||
maskOut();
|
||||
MaskOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1505,9 +1510,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
AttachmentDescription[] attachmentDescs = null;
|
||||
|
||||
var subpass = new SubpassDescription()
|
||||
var subpass = new SubpassDescription
|
||||
{
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||
};
|
||||
|
||||
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
||||
@ -1572,7 +1577,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||
{
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo()
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo
|
||||
{
|
||||
SType = StructureType.RenderPassCreateInfo,
|
||||
PAttachments = pAttachmentDescs,
|
||||
@ -1580,7 +1585,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PSubpasses = &subpass,
|
||||
SubpassCount = 1,
|
||||
PDependencies = &subpassDependency,
|
||||
DependencyCount = 1
|
||||
DependencyCount = 1,
|
||||
};
|
||||
|
||||
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 clearValue = new ClearValue();
|
||||
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo()
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo
|
||||
{
|
||||
SType = StructureType.RenderPassBeginInfo,
|
||||
RenderPass = _renderPass.Get(Cbs).Value,
|
||||
Framebuffer = _framebuffer.Get(Cbs).Value,
|
||||
RenderArea = renderArea,
|
||||
PClearValues = &clearValue,
|
||||
ClearValueCount = 1
|
||||
ClearValueCount = 1,
|
||||
};
|
||||
|
||||
Gd.Api.CmdBeginRenderPass(CommandBuffer, renderPassBeginInfo, SubpassContents.Inline);
|
||||
|
@ -2,6 +2,8 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Format = Silk.NET.Vulkan.Format;
|
||||
using PolygonMode = Silk.NET.Vulkan.PolygonMode;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@ -16,15 +18,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
AttachmentDescription[] attachmentDescs = null;
|
||||
|
||||
var subpass = new SubpassDescription()
|
||||
var subpass = new SubpassDescription
|
||||
{
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||
};
|
||||
|
||||
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[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 colorCount = 0;
|
||||
@ -106,7 +108,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||
{
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo()
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo
|
||||
{
|
||||
SType = StructureType.RenderPassCreateInfo,
|
||||
PAttachments = pAttachmentDescs,
|
||||
@ -114,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PSubpasses = &subpass,
|
||||
SubpassCount = 1,
|
||||
PDependencies = &subpassDependency,
|
||||
DependencyCount = 1
|
||||
DependencyCount = 1,
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
PipelineState pipeline = new PipelineState();
|
||||
PipelineState pipeline = new();
|
||||
pipeline.Initialize();
|
||||
|
||||
// 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.PatchControlPoints = state.PatchControlPoints;
|
||||
pipeline.PolygonMode = Silk.NET.Vulkan.PolygonMode.Fill; // Not implemented.
|
||||
pipeline.PolygonMode = PolygonMode.Fill; // Not implemented.
|
||||
pipeline.PrimitiveRestartEnable = state.PrimitiveRestartEnable;
|
||||
pipeline.RasterizerDiscardEnable = state.RasterizerDiscard;
|
||||
pipeline.SamplesCount = (uint)state.SamplesCount;
|
||||
|
@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Scissor = 1 << 2,
|
||||
Stencil = 1 << 3,
|
||||
Viewport = 1 << 4,
|
||||
All = Blend | DepthBias | Scissor | Stencil | Viewport
|
||||
All = Blend | DepthBias | Scissor | Stencil | Viewport,
|
||||
}
|
||||
|
||||
private DirtyFlags _dirty;
|
||||
@ -139,7 +139,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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);
|
||||
}
|
||||
@ -149,7 +149,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backWriteMask);
|
||||
|
@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private ulong _byteWeight;
|
||||
|
||||
private List<BufferHolder> _backingSwaps;
|
||||
private readonly List<BufferHolder> _backingSwaps;
|
||||
|
||||
public PipelineFull(VulkanRenderer gd, Device device) : base(gd, device)
|
||||
{
|
||||
@ -116,15 +116,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (Gd.Capabilities.SupportsConditionalRendering)
|
||||
{
|
||||
var buffer = evt.GetBuffer().Get(Cbs, 0, sizeof(long)).Value;
|
||||
var flags = isEqual ? ConditionalRenderingFlagsEXT.InvertedBitExt : 0;
|
||||
// var buffer = evt.GetBuffer().Get(Cbs, 0, sizeof(long)).Value;
|
||||
// var flags = isEqual ? ConditionalRenderingFlagsEXT.InvertedBitExt : 0;
|
||||
|
||||
var conditionalRenderingBeginInfo = new ConditionalRenderingBeginInfoEXT()
|
||||
{
|
||||
SType = StructureType.ConditionalRenderingBeginInfoExt,
|
||||
Buffer = buffer,
|
||||
Flags = flags
|
||||
};
|
||||
// var conditionalRenderingBeginInfo = new ConditionalRenderingBeginInfoEXT
|
||||
// {
|
||||
// SType = StructureType.ConditionalRenderingBeginInfoExt,
|
||||
// Buffer = buffer,
|
||||
// Flags = flags,
|
||||
// };
|
||||
|
||||
// Gd.ConditionalRenderingApi.CmdBeginConditionalRendering(CommandBuffer, conditionalRenderingBeginInfo);
|
||||
}
|
||||
@ -156,10 +156,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public CommandBufferScoped GetPreloadCommandBuffer()
|
||||
{
|
||||
if (PreloadCbs == null)
|
||||
{
|
||||
PreloadCbs = Gd.CommandBufferPool.Rent();
|
||||
}
|
||||
PreloadCbs ??= Gd.CommandBufferPool.Rent();
|
||||
|
||||
return PreloadCbs.Value;
|
||||
}
|
||||
@ -192,7 +189,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
CommandBufferScoped? cbs = null;
|
||||
|
||||
_backingSwaps.RemoveAll((holder) => holder.TryBackingSwap(ref cbs));
|
||||
_backingSwaps.RemoveAll(holder => holder.TryBackingSwap(ref cbs));
|
||||
|
||||
cbs?.Dispose();
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
HashCode hasher = new HashCode();
|
||||
HashCode hasher = new();
|
||||
|
||||
if (SetDescriptors != null)
|
||||
{
|
||||
@ -83,10 +83,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -45,23 +45,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
stages = activeStages;
|
||||
}
|
||||
|
||||
layoutBindings[descIndex] = new DescriptorSetLayoutBinding()
|
||||
layoutBindings[descIndex] = new DescriptorSetLayoutBinding
|
||||
{
|
||||
Binding = (uint)descriptor.Binding,
|
||||
DescriptorType = descriptor.Type.Convert(),
|
||||
DescriptorCount = (uint)descriptor.Count,
|
||||
StageFlags = stages.Convert()
|
||||
StageFlags = stages.Convert(),
|
||||
};
|
||||
}
|
||||
|
||||
fixed (DescriptorSetLayoutBinding* pLayoutBindings = layoutBindings)
|
||||
{
|
||||
var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
|
||||
var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
|
||||
{
|
||||
SType = StructureType.DescriptorSetLayoutCreateInfo,
|
||||
PBindings = pLayoutBindings,
|
||||
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();
|
||||
@ -72,11 +72,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (DescriptorSetLayout* pLayouts = layouts)
|
||||
{
|
||||
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
|
||||
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineLayoutCreateInfo,
|
||||
PSetLayouts = pLayouts,
|
||||
SetLayoutCount = (uint)layouts.Length
|
||||
SetLayoutCount = (uint)layouts.Length,
|
||||
};
|
||||
|
||||
gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
|
||||
|
@ -13,301 +13,301 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -325,10 +325,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
for (int index = 0; index < Constants.MaxShaderStages; index++)
|
||||
{
|
||||
StageRequiredSubgroupSizes[index] = new PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT()
|
||||
StageRequiredSubgroupSizes[index] = new PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.PipelineShaderStageRequiredSubgroupSizeCreateInfoExt,
|
||||
RequiredSubgroupSize = RequiredSubgroupSize
|
||||
RequiredSubgroupSize = RequiredSubgroupSize,
|
||||
};
|
||||
}
|
||||
|
||||
@ -357,12 +357,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
UpdateStageRequiredSubgroupSizes(gd, 1);
|
||||
}
|
||||
|
||||
var pipelineCreateInfo = new ComputePipelineCreateInfo()
|
||||
var pipelineCreateInfo = new ComputePipelineCreateInfo
|
||||
{
|
||||
SType = StructureType.ComputePipelineCreateInfo,
|
||||
Stage = Stages[0],
|
||||
BasePipelineIndex = -1,
|
||||
Layout = PipelineLayout
|
||||
Layout = PipelineLayout,
|
||||
};
|
||||
|
||||
Pipeline pipelineHandle = default;
|
||||
@ -431,7 +431,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
VertexAttributeDescriptionCount = VertexAttributeDescriptionsCount,
|
||||
PVertexAttributeDescriptions = isMoltenVk ? pVertexAttributeDescriptions2 : pVertexAttributeDescriptions,
|
||||
VertexBindingDescriptionCount = VertexBindingDescriptionsCount,
|
||||
PVertexBindingDescriptions = pVertexBindingDescriptions
|
||||
PVertexBindingDescriptions = pVertexBindingDescriptions,
|
||||
};
|
||||
|
||||
bool primitiveRestartEnable = PrimitiveRestartEnable;
|
||||
@ -453,20 +453,20 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
primitiveRestartEnable &= topologySupportsRestart;
|
||||
|
||||
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo()
|
||||
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
||||
PrimitiveRestartEnable = primitiveRestartEnable,
|
||||
Topology = Topology
|
||||
Topology = Topology,
|
||||
};
|
||||
|
||||
var tessellationState = new PipelineTessellationStateCreateInfo()
|
||||
var tessellationState = new PipelineTessellationStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineTessellationStateCreateInfo,
|
||||
PatchControlPoints = PatchControlPoints
|
||||
PatchControlPoints = PatchControlPoints,
|
||||
};
|
||||
|
||||
var rasterizationState = new PipelineRasterizationStateCreateInfo()
|
||||
var rasterizationState = new PipelineRasterizationStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineRasterizationStateCreateInfo,
|
||||
DepthClampEnable = DepthClampEnable,
|
||||
@ -478,24 +478,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DepthBiasEnable = DepthBiasEnable,
|
||||
DepthBiasClamp = DepthBiasClamp,
|
||||
DepthBiasConstantFactor = DepthBiasConstantFactor,
|
||||
DepthBiasSlopeFactor = DepthBiasSlopeFactor
|
||||
DepthBiasSlopeFactor = DepthBiasSlopeFactor,
|
||||
};
|
||||
|
||||
var viewportState = new PipelineViewportStateCreateInfo()
|
||||
var viewportState = new PipelineViewportStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineViewportStateCreateInfo,
|
||||
ViewportCount = ViewportsCount,
|
||||
PViewports = pViewports,
|
||||
ScissorCount = ScissorsCount,
|
||||
PScissors = pScissors
|
||||
PScissors = pScissors,
|
||||
};
|
||||
|
||||
if (gd.Capabilities.SupportsDepthClipControl)
|
||||
{
|
||||
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT()
|
||||
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt,
|
||||
NegativeOneToOne = DepthMode
|
||||
NegativeOneToOne = DepthMode,
|
||||
};
|
||||
|
||||
viewportState.PNext = &viewportDepthClipControlState;
|
||||
@ -508,7 +508,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
RasterizationSamples = TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, SamplesCount),
|
||||
MinSampleShading = 1,
|
||||
AlphaToCoverageEnable = AlphaToCoverageEnable,
|
||||
AlphaToOneEnable = AlphaToOneEnable
|
||||
AlphaToOneEnable = AlphaToOneEnable,
|
||||
};
|
||||
|
||||
var stencilFront = new StencilOpState(
|
||||
@ -529,7 +529,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
StencilBackWriteMask,
|
||||
StencilBackReference);
|
||||
|
||||
var depthStencilState = new PipelineDepthStencilStateCreateInfo()
|
||||
var depthStencilState = new PipelineDepthStencilStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineDepthStencilStateCreateInfo,
|
||||
DepthTestEnable = DepthTestEnable,
|
||||
@ -540,7 +540,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Front = stencilFront,
|
||||
Back = stencilBack,
|
||||
MinDepthBounds = MinDepthBounds,
|
||||
MaxDepthBounds = MaxDepthBounds
|
||||
MaxDepthBounds = MaxDepthBounds,
|
||||
};
|
||||
|
||||
uint blendEnables = 0;
|
||||
@ -564,13 +564,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
var colorBlendState = new PipelineColorBlendStateCreateInfo()
|
||||
var colorBlendState = new PipelineColorBlendStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
||||
LogicOpEnable = LogicOpEnable,
|
||||
LogicOp = LogicOp,
|
||||
AttachmentCount = ColorBlendAttachmentStateCount,
|
||||
PAttachments = pColorBlendAttachmentState
|
||||
PAttachments = pColorBlendAttachmentState,
|
||||
};
|
||||
|
||||
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
||||
@ -579,12 +579,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
!AdvancedBlendDstPreMultiplied ||
|
||||
AdvancedBlendOverlap != BlendOverlapEXT.UncorrelatedExt)
|
||||
{
|
||||
colorBlendAdvancedState = new PipelineColorBlendAdvancedStateCreateInfoEXT()
|
||||
colorBlendAdvancedState = new PipelineColorBlendAdvancedStateCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.PipelineColorBlendAdvancedStateCreateInfoExt,
|
||||
SrcPremultiplied = AdvancedBlendSrcPreMultiplied,
|
||||
DstPremultiplied = AdvancedBlendDstPreMultiplied,
|
||||
BlendOverlap = AdvancedBlendOverlap
|
||||
BlendOverlap = AdvancedBlendOverlap,
|
||||
};
|
||||
|
||||
colorBlendState.PNext = &colorBlendAdvancedState;
|
||||
@ -609,11 +609,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
dynamicStates[8] = DynamicState.VertexInputBindingStrideExt;
|
||||
}
|
||||
|
||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo()
|
||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineDynamicStateCreateInfo,
|
||||
DynamicStateCount = (uint)dynamicStatesCount,
|
||||
PDynamicStates = dynamicStates
|
||||
PDynamicStates = dynamicStates,
|
||||
};
|
||||
|
||||
if (gd.Capabilities.SupportsSubgroupSizeControl)
|
||||
@ -621,7 +621,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
UpdateStageRequiredSubgroupSizes(gd, (int)StagesCount);
|
||||
}
|
||||
|
||||
var pipelineCreateInfo = new GraphicsPipelineCreateInfo()
|
||||
var pipelineCreateInfo = new GraphicsPipelineCreateInfo
|
||||
{
|
||||
SType = StructureType.GraphicsPipelineCreateInfo,
|
||||
StageCount = StagesCount,
|
||||
@ -637,7 +637,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PDynamicState = &pipelineDynamicStateCreateInfo,
|
||||
Layout = PipelineLayout,
|
||||
RenderPass = renderPass,
|
||||
BasePipelineIndex = -1
|
||||
BasePipelineIndex = -1,
|
||||
};
|
||||
|
||||
gd.Api.CreateGraphicsPipelines(device, cache, 1, &pipelineCreateInfo, null, &pipelineHandle).ThrowOnError();
|
||||
@ -659,7 +659,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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++)
|
||||
{
|
||||
@ -728,7 +728,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
Stages.Dispose();
|
||||
StageRequiredSubgroupSizes.Dispose();
|
||||
|
@ -22,12 +22,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public ulong Id8;
|
||||
public ulong Id9;
|
||||
|
||||
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
|
||||
private uint ScissorsCount => (byte)(Id7 & 0xFF);
|
||||
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||
private readonly uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||
private readonly uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||
private readonly uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||
private readonly bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||
|
||||
public Array32<VertexInputAttributeDescription> VertexAttributeDescriptions;
|
||||
public Array33<VertexInputBindingDescription> VertexBindingDescriptions;
|
||||
@ -37,7 +35,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public Array9<Format> AttachmentFormats;
|
||||
public uint AttachmentIntegerFormatMask;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
public readonly override bool Equals(object obj)
|
||||
{
|
||||
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
|
||||
{
|
||||
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()
|
||||
|
@ -23,10 +23,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
private readonly BufferHolder _buffer;
|
||||
private readonly IntPtr _bufferMap;
|
||||
private readonly CounterType _type;
|
||||
private bool _result32Bit;
|
||||
private bool _isSupported;
|
||||
private readonly bool _result32Bit;
|
||||
private readonly bool _isSupported;
|
||||
|
||||
private long _defaultValue;
|
||||
private readonly long _defaultValue;
|
||||
private int? _resetSequence;
|
||||
|
||||
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.GeometryShaderPrimitivesBit : 0;
|
||||
|
||||
var queryPoolCreateInfo = new QueryPoolCreateInfo()
|
||||
var queryPoolCreateInfo = new QueryPoolCreateInfo
|
||||
{
|
||||
SType = StructureType.QueryPoolCreateInfo,
|
||||
QueryCount = 1,
|
||||
QueryType = GetQueryType(type),
|
||||
PipelineStatistics = flags
|
||||
PipelineStatistics = flags,
|
||||
};
|
||||
|
||||
gd.Api.CreateQueryPool(device, queryPoolCreateInfo, null, out _queryPool).ThrowOnError();
|
||||
@ -63,14 +63,14 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
private bool QueryTypeSupported(VulkanRenderer gd, CounterType type)
|
||||
private static bool QueryTypeSupported(VulkanRenderer gd, CounterType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
CounterType.SamplesPassed => true,
|
||||
CounterType.PrimitivesGenerated => gd.Capabilities.SupportsPipelineStatisticsQuery,
|
||||
CounterType.TransformFeedbackPrimitivesWritten => gd.Capabilities.SupportsTransformFeedbackQueries,
|
||||
_ => false
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
CounterType.SamplesPassed => QueryType.Occlusion,
|
||||
CounterType.PrimitivesGenerated => QueryType.PipelineStatistics,
|
||||
CounterType.TransformFeedbackPrimitivesWritten => QueryType.TransformFeedbackStreamExt,
|
||||
_ => QueryType.Occlusion
|
||||
_ => QueryType.Occlusion,
|
||||
};
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
_resetSequence = null;
|
||||
}
|
||||
|
||||
public unsafe void End(bool withResult)
|
||||
public void End(bool withResult)
|
||||
{
|
||||
if (_isSupported)
|
||||
{
|
||||
|
@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
public CounterType Type { get; }
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
private Queue<CounterQueueEvent> _events = new Queue<CounterQueueEvent>();
|
||||
private readonly Queue<CounterQueueEvent> _events = new();
|
||||
private CounterQueueEvent _current;
|
||||
|
||||
private ulong _accumulatedCounter;
|
||||
@ -26,12 +26,12 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
|
||||
private readonly object _lock = new();
|
||||
|
||||
private Queue<BufferedQuery> _queryPool;
|
||||
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
||||
private AutoResetEvent _wakeSignal = new AutoResetEvent(false);
|
||||
private AutoResetEvent _eventConsumed = new AutoResetEvent(false);
|
||||
private readonly Queue<BufferedQuery> _queryPool;
|
||||
private readonly AutoResetEvent _queuedEvent = new(false);
|
||||
private readonly AutoResetEvent _wakeSignal = new(false);
|
||||
private readonly AutoResetEvent _eventConsumed = new(false);
|
||||
|
||||
private Thread _consumerThread;
|
||||
private readonly Thread _consumerThread;
|
||||
|
||||
public int ResetSequence { get; private set; }
|
||||
|
||||
@ -116,10 +116,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
BufferedQuery result = _queryPool.Dequeue();
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new BufferedQuery(_gd, _device, _pipeline, Type, _gd.IsAmdWindows);
|
||||
}
|
||||
|
||||
return new BufferedQuery(_gd, _device, _pipeline, Type, _gd.IsAmdWindows);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
|
||||
public ulong DrawIndex { get; }
|
||||
|
||||
private CounterQueue _queue;
|
||||
private BufferedQuery _counter;
|
||||
private readonly CounterQueue _queue;
|
||||
private readonly BufferedQuery _counter;
|
||||
|
||||
private bool _hostAccessReserved = false;
|
||||
private bool _hostAccessReserved;
|
||||
private int _refCount = 1; // Starts with a reference from the counter queue.
|
||||
|
||||
private readonly object _lock = new();
|
||||
|
@ -19,4 +19,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Access = access;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ResourceType.StorageBuffer => PipelineBase.StorageSetIndex,
|
||||
ResourceType.TextureAndSampler or ResourceType.BufferTexture => PipelineBase.TextureSetIndex,
|
||||
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;
|
||||
@ -64,4 +64,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return new ResourceLayout(descriptors.AsReadOnly(), usages.AsReadOnly());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@ -8,13 +9,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly VulkanRenderer _gd;
|
||||
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.Samplers.Add(this);
|
||||
|
||||
(Filter minFilter, SamplerMipmapMode mipFilter) = EnumConversion.Convert(info.MinFilter);
|
||||
(Filter minFilter, SamplerMipmapMode mipFilter) = info.MinFilter.Convert();
|
||||
|
||||
float minLod = info.MinLod;
|
||||
float maxLod = info.MaxLod;
|
||||
@ -27,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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,
|
||||
MagFilter = info.MagFilter.Convert(),
|
||||
@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MinLod = minLod,
|
||||
MaxLod = maxLod,
|
||||
BorderColor = borderColor,
|
||||
UnnormalizedCoordinates = false // TODO: Use unnormalized coordinates.
|
||||
UnnormalizedCoordinates = false, // TODO: Use unnormalized coordinates.
|
||||
};
|
||||
|
||||
SamplerCustomBorderColorCreateInfoEXT customBorderColor;
|
||||
@ -57,10 +58,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
info.BorderColor.Blue,
|
||||
info.BorderColor.Alpha);
|
||||
|
||||
customBorderColor = new SamplerCustomBorderColorCreateInfoEXT()
|
||||
customBorderColor = new SamplerCustomBorderColorCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.SamplerCustomBorderColorCreateInfoExt,
|
||||
CustomBorderColor = color
|
||||
CustomBorderColor = color,
|
||||
};
|
||||
|
||||
samplerCreateInfo.PNext = &customBorderColor;
|
||||
@ -86,7 +87,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
cantConstrain = false;
|
||||
return BorderColor.FloatOpaqueBlack;
|
||||
}
|
||||
else if (a == 0f)
|
||||
|
||||
if (a == 0f)
|
||||
{
|
||||
cantConstrain = false;
|
||||
return BorderColor.FloatTransparentBlack;
|
||||
|
@ -11,16 +11,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Device _device;
|
||||
private VkSemaphore _semaphore;
|
||||
private int _referenceCount;
|
||||
public bool _disposed;
|
||||
private bool _disposed;
|
||||
|
||||
public unsafe SemaphoreHolder(Vk api, Device device)
|
||||
{
|
||||
_api = api;
|
||||
_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();
|
||||
|
@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
// The shaderc.net dependency's Options constructor and dispose are not thread safe.
|
||||
// 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");
|
||||
|
||||
@ -57,11 +57,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (byte* pCode = spirv)
|
||||
{
|
||||
var shaderModuleCreateInfo = new ShaderModuleCreateInfo()
|
||||
var shaderModuleCreateInfo = new ShaderModuleCreateInfo
|
||||
{
|
||||
SType = StructureType.ShaderModuleCreateInfo,
|
||||
CodeSize = (uint)spirv.Length,
|
||||
PCode = (uint*)pCode
|
||||
PCode = (uint*)pCode,
|
||||
};
|
||||
|
||||
api.CreateShaderModule(device, shaderModuleCreateInfo, null, out _module).ThrowOnError();
|
||||
@ -80,12 +80,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
options = new Options(false)
|
||||
{
|
||||
SourceLanguage = SourceLanguage.Glsl,
|
||||
TargetSpirVVersion = new SpirVVersion(1, 5)
|
||||
TargetSpirVVersion = new SpirVVersion(1, 5),
|
||||
};
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
lock (_shaderOptionsLock)
|
||||
@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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;
|
||||
}
|
||||
@ -134,12 +134,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public unsafe PipelineShaderStageCreateInfo GetInfo()
|
||||
{
|
||||
return new PipelineShaderStageCreateInfo()
|
||||
return new PipelineShaderStageCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineShaderStageCreateInfo,
|
||||
Stage = _stage,
|
||||
Module = _module,
|
||||
PName = (byte*)_ptrMainEntryPointName
|
||||
PName = (byte*)_ptrMainEntryPointName,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -47,13 +47,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private HashTableSlim<PipelineUid, Auto<DisposablePipeline>> _graphicsPipelineCache;
|
||||
private HashTableSlim<SpecData, Auto<DisposablePipeline>> _computePipelineCache;
|
||||
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
private Device _device;
|
||||
private bool _initialized;
|
||||
|
||||
private ProgramPipelineState _state;
|
||||
private DisposableRenderPass _dummyRenderPass;
|
||||
private Task _compileTask;
|
||||
private readonly Task _compileTask;
|
||||
private bool _firstBackgroundUse;
|
||||
|
||||
public ShaderCollection(
|
||||
@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ShaderStageFlags.GeometryBit => 2,
|
||||
ShaderStageFlags.TessellationControlBit => 3,
|
||||
ShaderStageFlags.TessellationEvaluationBit => 4,
|
||||
_ => 0
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
if (shader.StageFlags == ShaderStageFlags.ComputeBit)
|
||||
@ -143,7 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
for (int setIndex = 0; setIndex < sets.Count; setIndex++)
|
||||
{
|
||||
List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
|
||||
List<ResourceBindingSegment> currentSegments = new();
|
||||
|
||||
ResourceDescriptor currentDescriptor = default;
|
||||
int currentCount = 0;
|
||||
@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
for (int setIndex = 0; setIndex < setUsages.Count; setIndex++)
|
||||
{
|
||||
List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
|
||||
List<ResourceBindingSegment> currentSegments = new();
|
||||
|
||||
ResourceUsage currentUsage = default;
|
||||
int currentCount = 0;
|
||||
@ -319,7 +319,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return _infos;
|
||||
}
|
||||
|
||||
protected unsafe DisposableRenderPass CreateDummyRenderPass()
|
||||
protected DisposableRenderPass CreateDummyRenderPass()
|
||||
{
|
||||
if (_dummyRenderPass.Value.Handle != 0)
|
||||
{
|
||||
@ -331,7 +331,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void CreateBackgroundComputePipeline()
|
||||
{
|
||||
PipelineState pipeline = new PipelineState();
|
||||
PipelineState pipeline = new();
|
||||
pipeline.Initialize();
|
||||
|
||||
pipeline.Stages[0] = _shaders[0].GetInfo();
|
||||
@ -484,7 +484,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return _plce.GetNewDescriptorSetCollection(gd, commandBufferIndex, setIndex, out isNew);
|
||||
}
|
||||
|
||||
protected virtual unsafe void Dispose(bool disposing)
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
|
@ -2,8 +2,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
{
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
@ -329,8 +326,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -384,8 +380,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -486,8 +481,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -514,8 +508,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -545,8 +538,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -576,8 +568,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
@ -801,8 +791,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -933,8 +922,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
@ -1236,8 +1222,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
0x41, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xFD, 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,
|
||||
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,
|
||||
@ -1638,8 +1622,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
@ -2023,8 +2005,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -2081,8 +2062,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -2185,8 +2165,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -2288,8 +2267,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
@ -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,
|
||||
};
|
||||
|
||||
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,
|
||||
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,
|
||||
@ -2509,8 +2485,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
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,
|
||||
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,
|
||||
@ -2617,4 +2592,4 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x5F, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@ -13,7 +11,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Int64,
|
||||
Float16,
|
||||
Float32,
|
||||
Float64
|
||||
Float64,
|
||||
}
|
||||
|
||||
sealed class SpecDescription
|
||||
@ -36,10 +34,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
structSize += typeSize;
|
||||
}
|
||||
|
||||
Info = new SpecializationInfo()
|
||||
Info = new SpecializationInfo
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
Info = new SpecializationInfo()
|
||||
Info = new SpecializationInfo
|
||||
{
|
||||
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.Bool32 or SpecConstType.Int32 or SpecConstType.Float32 => 4,
|
||||
SpecConstType.Int64 or SpecConstType.Float64 => 8,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type)),
|
||||
};
|
||||
|
||||
private SpecDescription()
|
||||
@ -99,4 +97,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public override bool Equals(object obj) => obj is SpecData other && Equals(other);
|
||||
public bool Equals(ref SpecData other) => _data.AsSpan().SequenceEqual(other._data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_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;
|
||||
CommandBufferScoped scoped = cbs ?? cbp.Rent();
|
||||
@ -72,10 +72,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
int chunkSize = Math.Min(_freeSize, data.Length);
|
||||
|
||||
PushDataImpl(scoped, dst, dstOffset, data.Slice(0, chunkSize));
|
||||
PushDataImpl(scoped, dst, dstOffset, data[..chunkSize]);
|
||||
|
||||
dstOffset += chunkSize;
|
||||
data = data.Slice(chunkSize);
|
||||
data = data[chunkSize..];
|
||||
}
|
||||
|
||||
if (!isRender)
|
||||
@ -93,8 +93,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int capacity = BufferSize - offset;
|
||||
if (capacity < data.Length)
|
||||
{
|
||||
_buffer.SetDataUnchecked(offset, data.Slice(0, capacity));
|
||||
_buffer.SetDataUnchecked(0, data.Slice(capacity));
|
||||
_buffer.SetDataUnchecked(offset, data[..capacity]);
|
||||
_buffer.SetDataUnchecked(0, data[capacity..]);
|
||||
|
||||
BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, dstOffset, 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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -21,13 +21,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
private ulong _firstHandle = 0;
|
||||
private ulong _firstHandle;
|
||||
|
||||
private readonly VulkanRenderer _gd;
|
||||
private readonly Device _device;
|
||||
private List<SyncHandle> _handles;
|
||||
private ulong FlushId;
|
||||
private long WaitTicks;
|
||||
private readonly List<SyncHandle> _handles;
|
||||
private ulong _flushId;
|
||||
private long _waitTicks;
|
||||
|
||||
public SyncManager(VulkanRenderer gd, Device device)
|
||||
{
|
||||
@ -38,13 +38,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void RegisterFlush()
|
||||
{
|
||||
FlushId++;
|
||||
_flushId++;
|
||||
}
|
||||
|
||||
public void Create(ulong id, bool strict)
|
||||
{
|
||||
ulong flushId = FlushId;
|
||||
MultiFenceHolder waitable = new MultiFenceHolder();
|
||||
ulong flushId = _flushId;
|
||||
MultiFenceHolder waitable = new();
|
||||
if (strict || _gd.InterruptAction == null)
|
||||
{
|
||||
_gd.FlushAllCommands();
|
||||
@ -58,11 +58,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_gd.CommandBufferPool.AddInUseWaitable(waitable);
|
||||
}
|
||||
|
||||
SyncHandle handle = new SyncHandle
|
||||
SyncHandle handle = new()
|
||||
{
|
||||
ID = id,
|
||||
Waitable = waitable,
|
||||
FlushId = flushId
|
||||
FlushId = flushId,
|
||||
};
|
||||
|
||||
lock (_handles)
|
||||
@ -132,11 +132,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
long beforeTicks = Stopwatch.GetTimestamp();
|
||||
|
||||
if (result.NeedsFlush(FlushId))
|
||||
if (result.NeedsFlush(_flushId))
|
||||
{
|
||||
_gd.InterruptAction(() =>
|
||||
{
|
||||
if (result.NeedsFlush(FlushId))
|
||||
if (result.NeedsFlush(_flushId))
|
||||
{
|
||||
_gd.FlushAllCommands();
|
||||
}
|
||||
@ -158,7 +158,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitTicks += Stopwatch.GetTimestamp() - beforeTicks;
|
||||
_waitTicks += Stopwatch.GetTimestamp() - beforeTicks;
|
||||
result.Signalled = true;
|
||||
}
|
||||
}
|
||||
@ -177,7 +177,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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);
|
||||
if (signaled)
|
||||
@ -192,7 +195,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
first.Waitable = null;
|
||||
}
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
// This sync handle and any following have not been reached yet.
|
||||
break;
|
||||
@ -202,8 +206,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public long GetAndResetWaitTicks()
|
||||
{
|
||||
long result = WaitTicks;
|
||||
WaitTicks = 0;
|
||||
long result = _waitTicks;
|
||||
_waitTicks = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
@ -15,7 +16,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private int _offset;
|
||||
private int _size;
|
||||
private Auto<DisposableBufferView> _bufferView;
|
||||
private Dictionary<GAL.Format, Auto<DisposableBufferView>> _selfManagedViews;
|
||||
private Dictionary<Format, Auto<DisposableBufferView>> _selfManagedViews;
|
||||
|
||||
private int _bufferCount;
|
||||
|
||||
@ -131,15 +132,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public BufferView GetBufferView(CommandBufferScoped cbs, GAL.Format format)
|
||||
public BufferView GetBufferView(CommandBufferScoped cbs, Format format)
|
||||
{
|
||||
var vkFormat = FormatTable.GetFormat(format);
|
||||
if (vkFormat == VkFormat)
|
||||
@ -156,7 +154,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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;
|
||||
|
@ -80,12 +80,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
(srcOffsets.Element0, srcOffsets.Element1) = ExtentsToOffset3D(srcRegion, srcInfo.Width, srcInfo.Height, level);
|
||||
(dstOffsets.Element0, dstOffsets.Element1) = ExtentsToOffset3D(dstRegion, dstInfo.Width, dstInfo.Height, level);
|
||||
|
||||
var region = new ImageBlit()
|
||||
var region = new ImageBlit
|
||||
{
|
||||
SrcSubresource = srcSl,
|
||||
SrcOffsets = srcOffsets,
|
||||
DstSubresource = dstSl,
|
||||
DstOffsets = dstOffsets
|
||||
DstOffsets = dstOffsets,
|
||||
};
|
||||
|
||||
api.CmdBlitImage(commandBuffer, srcImage, ImageLayout.General, dstImage, ImageLayout.General, 1, region, filter);
|
||||
@ -219,21 +219,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
int dstZ;
|
||||
int dstLayer;
|
||||
int dstDepth;
|
||||
int dstLayers;
|
||||
|
||||
if (dstInfo.Target == Target.Texture3D)
|
||||
{
|
||||
dstZ = dstDepthOrLayer;
|
||||
dstLayer = 0;
|
||||
dstDepth = depthOrLayers;
|
||||
dstLayers = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dstZ = 0;
|
||||
dstLayer = dstDepthOrLayer;
|
||||
dstDepth = 1;
|
||||
dstLayers = depthOrLayers;
|
||||
}
|
||||
|
||||
@ -366,20 +363,20 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var dsAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 0, ImageLayout.General);
|
||||
var dsResolveAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 1, ImageLayout.General);
|
||||
|
||||
var subpassDsResolve = new SubpassDescriptionDepthStencilResolve()
|
||||
var subpassDsResolve = new SubpassDescriptionDepthStencilResolve
|
||||
{
|
||||
SType = StructureType.SubpassDescriptionDepthStencilResolve,
|
||||
PDepthStencilResolveAttachment = &dsResolveAttachmentReference,
|
||||
DepthResolveMode = ResolveModeFlags.SampleZeroBit,
|
||||
StencilResolveMode = ResolveModeFlags.SampleZeroBit
|
||||
StencilResolveMode = ResolveModeFlags.SampleZeroBit,
|
||||
};
|
||||
|
||||
var subpass = new SubpassDescription2()
|
||||
var subpass = new SubpassDescription2
|
||||
{
|
||||
SType = StructureType.SubpassDescription2,
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||
PDepthStencilAttachment = &dsAttachmentReference,
|
||||
PNext = &subpassDsResolve
|
||||
PNext = &subpassDsResolve,
|
||||
};
|
||||
|
||||
AttachmentDescription2[] attachmentDescs = new AttachmentDescription2[2];
|
||||
@ -414,7 +411,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (AttachmentDescription2* pAttachmentDescs = attachmentDescs)
|
||||
{
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo2()
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo2
|
||||
{
|
||||
SType = StructureType.RenderPassCreateInfo2,
|
||||
PAttachments = pAttachmentDescs,
|
||||
@ -422,7 +419,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PSubpasses = &subpass,
|
||||
SubpassCount = 1,
|
||||
PDependencies = &subpassDependency,
|
||||
DependencyCount = 1
|
||||
DependencyCount = 1,
|
||||
};
|
||||
|
||||
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[1] = dstView.Get(cbs).Value;
|
||||
|
||||
var framebufferCreateInfo = new FramebufferCreateInfo()
|
||||
var framebufferCreateInfo = new FramebufferCreateInfo
|
||||
{
|
||||
SType = StructureType.FramebufferCreateInfo,
|
||||
RenderPass = rp.Get(cbs).Value,
|
||||
@ -445,23 +442,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PAttachments = attachments,
|
||||
Width = (uint)src.Width,
|
||||
Height = (uint)src.Height,
|
||||
Layers = (uint)src.Layers
|
||||
Layers = (uint)src.Layers,
|
||||
};
|
||||
|
||||
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 clearValue = new ClearValue();
|
||||
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo()
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo
|
||||
{
|
||||
SType = StructureType.RenderPassBeginInfo,
|
||||
RenderPass = rp.Get(cbs).Value,
|
||||
Framebuffer = fb.Get(cbs).Value,
|
||||
RenderArea = renderArea,
|
||||
PClearValues = &clearValue,
|
||||
ClearValueCount = 1
|
||||
ClearValueCount = 1,
|
||||
};
|
||||
|
||||
// The resolve operation happens at the end of the subpass, so let's just do a begin/end
|
||||
|
@ -4,6 +4,7 @@ using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
@ -42,7 +43,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Auto<MemoryAllocation> _allocationAuto;
|
||||
private Auto<MemoryAllocation> _foreignAllocationAuto;
|
||||
|
||||
private Dictionary<GAL.Format, TextureStorage> _aliasedStorages;
|
||||
private Dictionary<Format, TextureStorage> _aliasedStorages;
|
||||
|
||||
private AccessFlags _lastModificationAccess;
|
||||
private PipelineStageFlags _lastModificationStage;
|
||||
@ -50,7 +51,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private PipelineStageFlags _lastReadStage;
|
||||
|
||||
private int _viewsCount;
|
||||
private ulong _size;
|
||||
private readonly ulong _size;
|
||||
|
||||
public VkFormat VkFormat { get; }
|
||||
public float ScaleFactor { get; }
|
||||
@ -98,7 +99,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
flags |= ImageCreateFlags.Create2DArrayCompatibleBit;
|
||||
}
|
||||
|
||||
var imageCreateInfo = new ImageCreateInfo()
|
||||
var imageCreateInfo = new ImageCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageCreateInfo,
|
||||
ImageType = type,
|
||||
@ -111,7 +112,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Usage = usage,
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
InitialLayout = ImageLayout.Undefined,
|
||||
Flags = flags
|
||||
Flags = flags,
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
GAL.Format.S8Uint => GAL.Format.R8Unorm,
|
||||
GAL.Format.D16Unorm => GAL.Format.R16Unorm,
|
||||
GAL.Format.S8UintD24Unorm => GAL.Format.R8G8B8A8Unorm,
|
||||
GAL.Format.D32Float => GAL.Format.R32Float,
|
||||
GAL.Format.D24UnormS8Uint => GAL.Format.R8G8B8A8Unorm,
|
||||
GAL.Format.D32FloatS8Uint => GAL.Format.R32G32Float,
|
||||
_ => throw new ArgumentException($"\"{format}\" is not a supported depth or stencil format.")
|
||||
Format.S8Uint => Format.R8Unorm,
|
||||
Format.D16Unorm => Format.R16Unorm,
|
||||
Format.S8UintD24Unorm => Format.R8G8B8A8Unorm,
|
||||
Format.D32Float => Format.R32Float,
|
||||
Format.D24UnormS8Uint => Format.R8G8B8A8Unorm,
|
||||
Format.D32FloatS8Uint => Format.R32G32Float,
|
||||
_ => throw new ArgumentException($"\"{format}\" is not a supported depth or stencil format."),
|
||||
};
|
||||
|
||||
return CreateAliasedStorageUnsafe(colorFormat);
|
||||
}
|
||||
|
||||
public TextureStorage CreateAliasedStorageUnsafe(GAL.Format format)
|
||||
public TextureStorage CreateAliasedStorageUnsafe(Format format)
|
||||
{
|
||||
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);
|
||||
|
||||
@ -182,14 +183,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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);
|
||||
}
|
||||
|
||||
public static TextureCreateInfo NewCreateInfoWith(
|
||||
ref TextureCreateInfo info,
|
||||
GAL.Format format,
|
||||
Format format,
|
||||
int bytesPerPixel,
|
||||
int width,
|
||||
int height)
|
||||
@ -262,7 +263,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, (uint)_info.Levels, 0, (uint)_info.GetLayers());
|
||||
|
||||
var barrier = new ImageMemoryBarrier()
|
||||
var barrier = new ImageMemoryBarrier
|
||||
{
|
||||
SType = StructureType.ImageMemoryBarrier,
|
||||
SrcAccessMask = 0,
|
||||
@ -272,7 +273,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
Image = _imageAuto.Get(cbs).Value,
|
||||
SubresourceRange = subresourceRange
|
||||
SubresourceRange = subresourceRange,
|
||||
};
|
||||
|
||||
_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;
|
||||
|
||||
|
@ -3,6 +3,7 @@ using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
@ -18,9 +19,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Auto<DisposableImageView> _imageViewDraw;
|
||||
private readonly Auto<DisposableImageView> _imageViewIdentity;
|
||||
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;
|
||||
|
||||
@ -68,16 +69,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var swizzleB = info.SwizzleB.Convert();
|
||||
var swizzleA = info.SwizzleA.Convert();
|
||||
|
||||
if (info.Format == GAL.Format.R5G5B5A1Unorm ||
|
||||
info.Format == GAL.Format.R5G5B5X1Unorm ||
|
||||
info.Format == GAL.Format.R5G6B5Unorm)
|
||||
if (info.Format == Format.R5G5B5A1Unorm ||
|
||||
info.Format == Format.R5G5B5X1Unorm ||
|
||||
info.Format == Format.R5G6B5Unorm)
|
||||
{
|
||||
var temp = swizzleR;
|
||||
|
||||
swizzleR = swizzleB;
|
||||
swizzleB = temp;
|
||||
(swizzleB, swizzleR) = (swizzleR, swizzleB);
|
||||
}
|
||||
else if (VkFormat == VkFormat.R4G4B4A4UnormPack16 || info.Format == GAL.Format.A1B5G5R5Unorm)
|
||||
else if (VkFormat == VkFormat.R4G4B4A4UnormPack16 || info.Format == Format.A1B5G5R5Unorm)
|
||||
{
|
||||
var tempB = swizzleB;
|
||||
var tempA = swizzleA;
|
||||
@ -98,13 +96,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
unsafe Auto<DisposableImageView> CreateImageView(ComponentMapping cm, ImageSubresourceRange sr, ImageViewType viewType, ImageUsageFlags usageFlags)
|
||||
{
|
||||
var usage = new ImageViewUsageCreateInfo()
|
||||
var usage = new ImageViewUsageCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageViewUsageCreateInfo,
|
||||
Usage = usageFlags
|
||||
Usage = usageFlags,
|
||||
};
|
||||
|
||||
var imageCreateInfo = new ImageViewCreateInfo()
|
||||
var imageCreateInfo = new ImageViewCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageViewCreateInfo,
|
||||
Image = storage.GetImageForViewCreation(),
|
||||
@ -112,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Format = format,
|
||||
Components = cm,
|
||||
SubresourceRange = sr,
|
||||
PNext = &usage
|
||||
PNext = &usage,
|
||||
};
|
||||
|
||||
gd.Api.CreateImageView(device, imageCreateInfo, null, out var imageView).ThrowOnError();
|
||||
@ -354,8 +352,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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(
|
||||
_gd.Api,
|
||||
@ -444,7 +443,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int layers,
|
||||
int levels)
|
||||
{
|
||||
ImageMemoryBarrier memoryBarrier = new ImageMemoryBarrier()
|
||||
ImageMemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.ImageMemoryBarrier,
|
||||
SrcAccessMask = srcAccessMask,
|
||||
@ -454,7 +453,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Image = image,
|
||||
OldLayout = 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(
|
||||
@ -470,7 +469,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
memoryBarrier);
|
||||
}
|
||||
|
||||
public TextureView GetView(GAL.Format format)
|
||||
public TextureView GetView(Format format)
|
||||
{
|
||||
if (format == Info.Format)
|
||||
{
|
||||
@ -499,7 +498,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Info.SwizzleB,
|
||||
Info.SwizzleA), 0, 0);
|
||||
|
||||
(_selfManagedViews ??= new Dictionary<GAL.Format, TextureView>()).Add(format, view);
|
||||
(_selfManagedViews ??= new Dictionary<Format, TextureView>()).Add(format, view);
|
||||
|
||||
return view;
|
||||
}
|
||||
@ -543,10 +542,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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)
|
||||
@ -559,10 +556,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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)
|
||||
@ -686,11 +681,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return length;
|
||||
}
|
||||
|
||||
private GAL.Format GetCompatibleGalFormat(GAL.Format format)
|
||||
private Format GetCompatibleGalFormat(Format format)
|
||||
{
|
||||
if (NeedsD24S8Conversion())
|
||||
{
|
||||
return GAL.Format.D32FloatS8Uint;
|
||||
return Format.D32FloatS8Uint;
|
||||
}
|
||||
|
||||
return format;
|
||||
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Broadcom,
|
||||
Qualcomm,
|
||||
Apple,
|
||||
Unknown
|
||||
Unknown,
|
||||
}
|
||||
|
||||
static partial class VendorUtils
|
||||
@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
0x14E4 => Vendor.Broadcom,
|
||||
0x8086 => Vendor.Intel,
|
||||
0x5143 => Vendor.Qualcomm,
|
||||
_ => Vendor.Unknown
|
||||
_ => Vendor.Unknown,
|
||||
};
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
0x10004 => "Codeplay Software Ltd.",
|
||||
0x10005 => "Mesa",
|
||||
0x10006 => "PoCL",
|
||||
_ => $"0x{id:X}"
|
||||
_ => $"0x{id:X}",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
using BufferHandle = Ryujinx.Graphics.GAL.BufferHandle;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
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 _size;
|
||||
@ -74,17 +74,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
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);
|
||||
|
||||
// The original stride must be reapplied in case it was rewritten.
|
||||
state.Internal.VertexBindingDescriptions[DescriptorIndex].Stride = (uint)_stride;
|
||||
|
||||
if (_offset >= size)
|
||||
{
|
||||
autoBuffer = null;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@ -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.
|
||||
|
||||
|
@ -1,21 +1,19 @@
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
|
||||
using System;
|
||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal class VertexBufferUpdater : IDisposable
|
||||
{
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
|
||||
private uint _baseBinding;
|
||||
private uint _count;
|
||||
|
||||
private NativeArray<VkBuffer> _buffers;
|
||||
private NativeArray<ulong> _offsets;
|
||||
private NativeArray<ulong> _sizes;
|
||||
private NativeArray<ulong> _strides;
|
||||
private readonly NativeArray<VkBuffer> _buffers;
|
||||
private readonly NativeArray<ulong> _offsets;
|
||||
private readonly NativeArray<ulong> _sizes;
|
||||
private readonly NativeArray<ulong> _strides;
|
||||
|
||||
public VertexBufferUpdater(VulkanRenderer gd)
|
||||
{
|
||||
|
@ -10,8 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
class VulkanDebugMessenger : IDisposable
|
||||
{
|
||||
private static string[] _excludedMessages = new string[]
|
||||
{
|
||||
private static readonly string[] _excludedMessages = {
|
||||
// NOTE: Done on purpose right now.
|
||||
"UNASSIGNED-CoreValidation-Shader-OutputNotConsumed",
|
||||
// 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.
|
||||
"UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout",
|
||||
// TODO: Fix this, it's causing too much noise right now.
|
||||
"VUID-VkSubpassDependency-srcSubpass-00867"
|
||||
"VUID-VkSubpassDependency-srcSubpass-00867",
|
||||
};
|
||||
|
||||
private readonly Vk _api;
|
||||
@ -48,7 +47,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private Result TryInitialize(out DebugUtilsMessengerEXT? debugUtilsMessengerHandle)
|
||||
{
|
||||
debugUtilsMessengerHandle = null;
|
||||
|
||||
|
||||
if (_debugUtils != null && _logLevel != GraphicsDebugLevel.None)
|
||||
{
|
||||
var messageType = _logLevel switch
|
||||
@ -59,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
GraphicsDebugLevel.All => DebugUtilsMessageTypeFlagsEXT.GeneralBitExt |
|
||||
DebugUtilsMessageTypeFlagsEXT.ValidationBitExt |
|
||||
DebugUtilsMessageTypeFlagsEXT.PerformanceBitExt,
|
||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\".")
|
||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
||||
};
|
||||
|
||||
var messageSeverity = _logLevel switch
|
||||
@ -71,14 +70,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DebugUtilsMessageSeverityFlagsEXT.WarningBitExt |
|
||||
DebugUtilsMessageSeverityFlagsEXT.VerboseBitExt |
|
||||
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,
|
||||
MessageType = messageType,
|
||||
MessageSeverity = messageSeverity
|
||||
MessageSeverity = messageSeverity,
|
||||
};
|
||||
|
||||
unsafe
|
||||
|
@ -14,14 +14,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public unsafe static class VulkanInitialization
|
||||
{
|
||||
private const uint InvalidIndex = uint.MaxValue;
|
||||
private static uint MinimalVulkanVersion = Vk.Version11.Value;
|
||||
private static uint MinimalInstanceVulkanVersion = Vk.Version12.Value;
|
||||
private static uint MaximumVulkanVersion = Vk.Version12.Value;
|
||||
private static readonly uint _minimalVulkanVersion = Vk.Version11.Value;
|
||||
private static readonly uint _minimalInstanceVulkanVersion = Vk.Version12.Value;
|
||||
private static readonly uint _maximumVulkanVersion = Vk.Version12.Value;
|
||||
private const string AppName = "Ryujinx.Graphics.Vulkan";
|
||||
private const int QueuesCount = 2;
|
||||
|
||||
private static readonly string[] _desirableExtensions = new string[]
|
||||
{
|
||||
private static readonly string[] _desirableExtensions = {
|
||||
ExtConditionalRendering.ExtensionName,
|
||||
ExtExtendedDynamicState.ExtensionName,
|
||||
ExtTransformFeedback.ExtensionName,
|
||||
@ -42,12 +41,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
"VK_NV_geometry_shader_passthrough",
|
||||
"VK_NV_viewport_array2",
|
||||
"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[]
|
||||
{
|
||||
KhrSwapchain.ExtensionName
|
||||
private static readonly string[] _requiredExtensions = {
|
||||
KhrSwapchain.ExtensionName,
|
||||
};
|
||||
|
||||
internal static VulkanInstance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions)
|
||||
@ -89,7 +87,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ApplicationVersion = 1,
|
||||
PEngineName = (byte*)appName,
|
||||
EngineVersion = 1,
|
||||
ApiVersion = MaximumVulkanVersion
|
||||
ApiVersion = _maximumVulkanVersion,
|
||||
};
|
||||
|
||||
IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];
|
||||
@ -112,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PpEnabledExtensionNames = (byte**)ppEnabledExtensions,
|
||||
PpEnabledLayerNames = (byte**)ppEnabledLayers,
|
||||
EnabledExtensionCount = (uint)enabledExtensions.Length,
|
||||
EnabledLayerCount = (uint)enabledLayers.Count
|
||||
EnabledLayerCount = (uint)enabledLayers.Count,
|
||||
};
|
||||
|
||||
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out var instance);
|
||||
@ -169,7 +167,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ApplicationVersion = 1,
|
||||
PEngineName = (byte*)appName,
|
||||
EngineVersion = 1,
|
||||
ApiVersion = MaximumVulkanVersion
|
||||
ApiVersion = _maximumVulkanVersion,
|
||||
};
|
||||
|
||||
var instanceCreateInfo = new InstanceCreateInfo
|
||||
@ -179,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PpEnabledExtensionNames = null,
|
||||
PpEnabledLayerNames = null,
|
||||
EnabledExtensionCount = 0,
|
||||
EnabledLayerCount = 0
|
||||
EnabledLayerCount = 0,
|
||||
};
|
||||
|
||||
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
|
||||
// TODO: Remove this once we relax our initialization codepaths.
|
||||
if (instance.InstanceVersion < MinimalInstanceVulkanVersion)
|
||||
if (instance.InstanceVersion < _minimalInstanceVulkanVersion)
|
||||
{
|
||||
return Array.Empty<DeviceInfo>();
|
||||
}
|
||||
|
||||
instance.EnumeratePhysicalDevices(out VulkanPhysicalDevice[] physicalDevices).ThrowOnError();
|
||||
|
||||
List<DeviceInfo> deviceInfos = new List<DeviceInfo>();
|
||||
List<DeviceInfo> deviceInfos = new();
|
||||
|
||||
foreach (VulkanPhysicalDevice physicalDevice in physicalDevices)
|
||||
{
|
||||
if (physicalDevice.PhysicalDeviceProperties.ApiVersion < MinimalVulkanVersion)
|
||||
if (physicalDevice.PhysicalDeviceProperties.ApiVersion < _minimalVulkanVersion)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -278,33 +276,33 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
queuePriorities[i] = 1f;
|
||||
}
|
||||
|
||||
var queueCreateInfo = new DeviceQueueCreateInfo()
|
||||
var queueCreateInfo = new DeviceQueueCreateInfo
|
||||
{
|
||||
SType = StructureType.DeviceQueueCreateInfo,
|
||||
QueueFamilyIndex = queueFamilyIndex,
|
||||
QueueCount = queueCount,
|
||||
PQueuePriorities = queuePriorities
|
||||
PQueuePriorities = queuePriorities,
|
||||
};
|
||||
|
||||
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,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
features2.PNext = &supportedFeaturesVk11;
|
||||
|
||||
PhysicalDeviceCustomBorderColorFeaturesEXT supportedFeaturesCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
||||
PhysicalDeviceCustomBorderColorFeaturesEXT supportedFeaturesCustomBorderColor = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_custom_border_color"))
|
||||
@ -312,10 +310,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.PNext = &supportedFeaturesCustomBorderColor;
|
||||
}
|
||||
|
||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT supportedFeaturesPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT()
|
||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT supportedFeaturesPrimitiveTopologyListRestart = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
||||
@ -323,10 +321,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.PNext = &supportedFeaturesPrimitiveTopologyListRestart;
|
||||
}
|
||||
|
||||
PhysicalDeviceTransformFeedbackFeaturesEXT supportedFeaturesTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
||||
PhysicalDeviceTransformFeedbackFeaturesEXT supportedFeaturesTransformFeedback = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName))
|
||||
@ -334,9 +332,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.PNext = &supportedFeaturesTransformFeedback;
|
||||
}
|
||||
|
||||
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt
|
||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_robustness2"))
|
||||
@ -346,10 +344,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.PNext = &supportedFeaturesRobustness2;
|
||||
}
|
||||
|
||||
PhysicalDeviceDepthClipControlFeaturesEXT supportedFeaturesDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
|
||||
PhysicalDeviceDepthClipControlFeaturesEXT supportedFeaturesDepthClipControl = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control"))
|
||||
@ -361,7 +359,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
var supportedFeatures = features2.Features;
|
||||
|
||||
var features = new PhysicalDeviceFeatures()
|
||||
var features = new PhysicalDeviceFeatures
|
||||
{
|
||||
DepthBiasClamp = supportedFeatures.DepthBiasClamp,
|
||||
DepthClamp = supportedFeatures.DepthClamp,
|
||||
@ -383,7 +381,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// ShaderStorageImageWriteWithoutFormat = true,
|
||||
TessellationShader = supportedFeatures.TessellationShader,
|
||||
VertexPipelineStoresAndAtomics = supportedFeatures.VertexPipelineStoresAndAtomics,
|
||||
RobustBufferAccess = useRobustBufferAccess
|
||||
RobustBufferAccess = useRobustBufferAccess,
|
||||
};
|
||||
|
||||
void* pExtendedFeatures = null;
|
||||
@ -392,11 +390,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName))
|
||||
{
|
||||
featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
||||
featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
TransformFeedback = supportedFeaturesTransformFeedback.TransformFeedback
|
||||
TransformFeedback = supportedFeaturesTransformFeedback.TransformFeedback,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresTransformFeedback;
|
||||
@ -406,12 +404,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
||||
{
|
||||
featuresPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT()
|
||||
featuresPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
PrimitiveTopologyListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyListRestart,
|
||||
PrimitiveTopologyPatchListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyPatchListRestart
|
||||
PrimitiveTopologyPatchListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyPatchListRestart,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresPrimitiveTopologyListRestart;
|
||||
@ -421,41 +419,41 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_robustness2"))
|
||||
{
|
||||
featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||
featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
NullDescriptor = supportedFeaturesRobustness2.NullDescriptor
|
||||
NullDescriptor = supportedFeaturesRobustness2.NullDescriptor,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresRobustness2;
|
||||
}
|
||||
|
||||
var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT()
|
||||
var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
ExtendedDynamicState = physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName)
|
||||
ExtendedDynamicState = physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName),
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresExtendedDynamicState;
|
||||
|
||||
var featuresVk11 = new PhysicalDeviceVulkan11Features()
|
||||
var featuresVk11 = new PhysicalDeviceVulkan11Features
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||
PNext = pExtendedFeatures,
|
||||
ShaderDrawParameters = supportedFeaturesVk11.ShaderDrawParameters
|
||||
ShaderDrawParameters = supportedFeaturesVk11.ShaderDrawParameters,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresVk11;
|
||||
|
||||
var featuresVk12 = new PhysicalDeviceVulkan12Features()
|
||||
var featuresVk12 = new PhysicalDeviceVulkan12Features
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceVulkan12Features,
|
||||
PNext = pExtendedFeatures,
|
||||
DescriptorIndexing = physicalDevice.IsDeviceExtensionPresent("VK_EXT_descriptor_indexing"),
|
||||
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;
|
||||
@ -464,11 +462,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_index_type_uint8"))
|
||||
{
|
||||
featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT()
|
||||
featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
IndexTypeUint8 = true
|
||||
IndexTypeUint8 = true,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresIndexU8;
|
||||
@ -478,11 +476,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_fragment_shader_interlock"))
|
||||
{
|
||||
featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT()
|
||||
featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceFragmentShaderInterlockFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
FragmentShaderPixelInterlock = true
|
||||
FragmentShaderPixelInterlock = true,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresFragmentShaderInterlock;
|
||||
@ -492,11 +490,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_subgroup_size_control"))
|
||||
{
|
||||
featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT()
|
||||
featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceSubgroupSizeControlFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
SubgroupSizeControl = true
|
||||
SubgroupSizeControl = true,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresSubgroupSizeControl;
|
||||
@ -508,7 +506,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
supportedFeaturesCustomBorderColor.CustomBorderColors &&
|
||||
supportedFeaturesCustomBorderColor.CustomBorderColorWithoutFormat)
|
||||
{
|
||||
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
||||
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
@ -524,11 +522,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control") &&
|
||||
supportedFeaturesDepthClipControl.DepthClipControl)
|
||||
{
|
||||
featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
|
||||
featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
DepthClipControl = true
|
||||
DepthClipControl = true,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresDepthClipControl;
|
||||
@ -543,7 +541,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
|
||||
}
|
||||
|
||||
var deviceCreateInfo = new DeviceCreateInfo()
|
||||
var deviceCreateInfo = new DeviceCreateInfo
|
||||
{
|
||||
SType = StructureType.DeviceCreateInfo,
|
||||
PNext = pExtendedFeatures,
|
||||
@ -551,7 +549,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PQueueCreateInfos = &queueCreateInfo,
|
||||
PpEnabledExtensionNames = (byte**)ppEnabledExtensions,
|
||||
EnabledExtensionCount = (uint)enabledExtensions.Length,
|
||||
PEnabledFeatures = &features
|
||||
PEnabledFeatures = &features,
|
||||
};
|
||||
|
||||
api.CreateDevice(physicalDevice.PhysicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();
|
||||
|
@ -11,6 +11,9 @@ using Silk.NET.Vulkan.Extensions.KHR;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
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
|
||||
{
|
||||
@ -143,14 +146,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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");
|
||||
@ -161,9 +164,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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");
|
||||
@ -175,9 +178,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
bool supportsTransformFeedback = _physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName);
|
||||
|
||||
PhysicalDeviceTransformFeedbackPropertiesEXT propertiesTransformFeedback = new PhysicalDeviceTransformFeedbackPropertiesEXT()
|
||||
PhysicalDeviceTransformFeedbackPropertiesEXT propertiesTransformFeedback = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceTransformFeedbackPropertiesExt
|
||||
SType = StructureType.PhysicalDeviceTransformFeedbackPropertiesExt,
|
||||
};
|
||||
|
||||
if (supportsTransformFeedback)
|
||||
@ -186,44 +189,44 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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"))
|
||||
@ -359,7 +362,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_counters = new Counters(this, _device, _pipeline);
|
||||
}
|
||||
|
||||
private unsafe void SetupContext(GraphicsDebugLevel logLevel)
|
||||
private void SetupContext(GraphicsDebugLevel logLevel)
|
||||
{
|
||||
_instance = VulkanInitialization.CreateInstance(Api, logLevel, _getRequiredExtensions());
|
||||
_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);
|
||||
}
|
||||
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)
|
||||
@ -426,7 +427,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
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);
|
||||
}
|
||||
@ -483,83 +484,83 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
FormatFeatureFlags.TransferDstBit;
|
||||
|
||||
bool supportsBc123CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.Bc1RgbaSrgb,
|
||||
GAL.Format.Bc1RgbaUnorm,
|
||||
GAL.Format.Bc2Srgb,
|
||||
GAL.Format.Bc2Unorm,
|
||||
GAL.Format.Bc3Srgb,
|
||||
GAL.Format.Bc3Unorm);
|
||||
Format.Bc1RgbaSrgb,
|
||||
Format.Bc1RgbaUnorm,
|
||||
Format.Bc2Srgb,
|
||||
Format.Bc2Unorm,
|
||||
Format.Bc3Srgb,
|
||||
Format.Bc3Unorm);
|
||||
|
||||
bool supportsBc45CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.Bc4Snorm,
|
||||
GAL.Format.Bc4Unorm,
|
||||
GAL.Format.Bc5Snorm,
|
||||
GAL.Format.Bc5Unorm);
|
||||
Format.Bc4Snorm,
|
||||
Format.Bc4Unorm,
|
||||
Format.Bc5Snorm,
|
||||
Format.Bc5Unorm);
|
||||
|
||||
bool supportsBc67CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.Bc6HSfloat,
|
||||
GAL.Format.Bc6HUfloat,
|
||||
GAL.Format.Bc7Srgb,
|
||||
GAL.Format.Bc7Unorm);
|
||||
Format.Bc6HSfloat,
|
||||
Format.Bc6HUfloat,
|
||||
Format.Bc7Srgb,
|
||||
Format.Bc7Unorm);
|
||||
|
||||
bool supportsEtc2CompressionFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.Etc2RgbaSrgb,
|
||||
GAL.Format.Etc2RgbaUnorm,
|
||||
GAL.Format.Etc2RgbPtaSrgb,
|
||||
GAL.Format.Etc2RgbPtaUnorm,
|
||||
GAL.Format.Etc2RgbSrgb,
|
||||
GAL.Format.Etc2RgbUnorm);
|
||||
Format.Etc2RgbaSrgb,
|
||||
Format.Etc2RgbaUnorm,
|
||||
Format.Etc2RgbPtaSrgb,
|
||||
Format.Etc2RgbPtaUnorm,
|
||||
Format.Etc2RgbSrgb,
|
||||
Format.Etc2RgbUnorm);
|
||||
|
||||
bool supports5BitComponentFormat = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.R5G6B5Unorm,
|
||||
GAL.Format.R5G5B5A1Unorm,
|
||||
GAL.Format.R5G5B5X1Unorm,
|
||||
GAL.Format.B5G6R5Unorm,
|
||||
GAL.Format.B5G5R5A1Unorm,
|
||||
GAL.Format.A1B5G5R5Unorm);
|
||||
Format.R5G6B5Unorm,
|
||||
Format.R5G5B5A1Unorm,
|
||||
Format.R5G5B5X1Unorm,
|
||||
Format.B5G6R5Unorm,
|
||||
Format.B5G5R5A1Unorm,
|
||||
Format.A1B5G5R5Unorm);
|
||||
|
||||
bool supportsR4G4B4A4Format = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.R4G4B4A4Unorm);
|
||||
Format.R4G4B4A4Unorm);
|
||||
|
||||
bool supportsAstcFormats = FormatCapabilities.OptimalFormatsSupport(compressedFormatFeatureFlags,
|
||||
GAL.Format.Astc4x4Unorm,
|
||||
GAL.Format.Astc5x4Unorm,
|
||||
GAL.Format.Astc5x5Unorm,
|
||||
GAL.Format.Astc6x5Unorm,
|
||||
GAL.Format.Astc6x6Unorm,
|
||||
GAL.Format.Astc8x5Unorm,
|
||||
GAL.Format.Astc8x6Unorm,
|
||||
GAL.Format.Astc8x8Unorm,
|
||||
GAL.Format.Astc10x5Unorm,
|
||||
GAL.Format.Astc10x6Unorm,
|
||||
GAL.Format.Astc10x8Unorm,
|
||||
GAL.Format.Astc10x10Unorm,
|
||||
GAL.Format.Astc12x10Unorm,
|
||||
GAL.Format.Astc12x12Unorm,
|
||||
GAL.Format.Astc4x4Srgb,
|
||||
GAL.Format.Astc5x4Srgb,
|
||||
GAL.Format.Astc5x5Srgb,
|
||||
GAL.Format.Astc6x5Srgb,
|
||||
GAL.Format.Astc6x6Srgb,
|
||||
GAL.Format.Astc8x5Srgb,
|
||||
GAL.Format.Astc8x6Srgb,
|
||||
GAL.Format.Astc8x8Srgb,
|
||||
GAL.Format.Astc10x5Srgb,
|
||||
GAL.Format.Astc10x6Srgb,
|
||||
GAL.Format.Astc10x8Srgb,
|
||||
GAL.Format.Astc10x10Srgb,
|
||||
GAL.Format.Astc12x10Srgb,
|
||||
GAL.Format.Astc12x12Srgb);
|
||||
Format.Astc4x4Unorm,
|
||||
Format.Astc5x4Unorm,
|
||||
Format.Astc5x5Unorm,
|
||||
Format.Astc6x5Unorm,
|
||||
Format.Astc6x6Unorm,
|
||||
Format.Astc8x5Unorm,
|
||||
Format.Astc8x6Unorm,
|
||||
Format.Astc8x8Unorm,
|
||||
Format.Astc10x5Unorm,
|
||||
Format.Astc10x6Unorm,
|
||||
Format.Astc10x8Unorm,
|
||||
Format.Astc10x10Unorm,
|
||||
Format.Astc12x10Unorm,
|
||||
Format.Astc12x12Unorm,
|
||||
Format.Astc4x4Srgb,
|
||||
Format.Astc5x4Srgb,
|
||||
Format.Astc5x5Srgb,
|
||||
Format.Astc6x5Srgb,
|
||||
Format.Astc6x6Srgb,
|
||||
Format.Astc8x5Srgb,
|
||||
Format.Astc8x6Srgb,
|
||||
Format.Astc8x8Srgb,
|
||||
Format.Astc10x5Srgb,
|
||||
Format.Astc10x6Srgb,
|
||||
Format.Astc10x8Srgb,
|
||||
Format.Astc10x10Srgb,
|
||||
Format.Astc12x10Srgb,
|
||||
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,
|
||||
PNext = &featuresVk12
|
||||
PNext = &featuresVk12,
|
||||
};
|
||||
|
||||
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}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return ParseStandardVulkanVersion(driverVersionRaw);
|
||||
}
|
||||
|
||||
return ParseStandardVulkanVersion(driverVersionRaw);
|
||||
}
|
||||
|
||||
private unsafe void PrintGpuInformation()
|
||||
@ -696,24 +695,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
||||
}
|
||||
|
||||
internal GAL.PrimitiveTopology TopologyRemap(GAL.PrimitiveTopology topology)
|
||||
internal PrimitiveTopology TopologyRemap(PrimitiveTopology topology)
|
||||
{
|
||||
return topology switch
|
||||
{
|
||||
GAL.PrimitiveTopology.Quads => GAL.PrimitiveTopology.Triangles,
|
||||
GAL.PrimitiveTopology.QuadStrip => GAL.PrimitiveTopology.TriangleStrip,
|
||||
GAL.PrimitiveTopology.TriangleFan => Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.NoTriangleFans) ? GAL.PrimitiveTopology.Triangles : topology,
|
||||
_ => topology
|
||||
PrimitiveTopology.Quads => PrimitiveTopology.Triangles,
|
||||
PrimitiveTopology.QuadStrip => PrimitiveTopology.TriangleStrip,
|
||||
PrimitiveTopology.TriangleFan => Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.NoTriangleFans) ? PrimitiveTopology.Triangles : topology,
|
||||
_ => topology,
|
||||
};
|
||||
}
|
||||
|
||||
internal bool TopologyUnsupported(GAL.PrimitiveTopology topology)
|
||||
internal bool TopologyUnsupported(PrimitiveTopology topology)
|
||||
{
|
||||
return topology switch
|
||||
{
|
||||
GAL.PrimitiveTopology.Quads => true,
|
||||
GAL.PrimitiveTopology.TriangleFan => Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.NoTriangleFans),
|
||||
_ => false
|
||||
PrimitiveTopology.Quads => true,
|
||||
PrimitiveTopology.TriangleFan => Capabilities.PortabilitySubset.HasFlag(PortabilitySubsetFlags.NoTriangleFans),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -873,4 +872,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
HostMemoryAllocator.TryImport(BufferManager.HostImportedBufferMemoryRequirements, BufferManager.DefaultBufferMemoryFlags, address, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
CreateSwapchain();
|
||||
|
||||
var semaphoreCreateInfo = new SemaphoreCreateInfo()
|
||||
var semaphoreCreateInfo = new SemaphoreCreateInfo
|
||||
{
|
||||
SType = StructureType.SemaphoreCreateInfo
|
||||
SType = StructureType.SemaphoreCreateInfo,
|
||||
};
|
||||
|
||||
gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _imageAvailableSemaphore).ThrowOnError();
|
||||
@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
var oldSwapchain = _swapchain;
|
||||
|
||||
var swapchainCreateInfo = new SwapchainCreateInfoKHR()
|
||||
var swapchainCreateInfo = new SwapchainCreateInfoKHR
|
||||
{
|
||||
SType = StructureType.SwapchainCreateInfoKhr,
|
||||
Surface = _surface,
|
||||
@ -130,7 +130,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PreTransform = capabilities.CurrentTransform,
|
||||
CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
|
||||
PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
|
||||
Clipped = true
|
||||
Clipped = true,
|
||||
};
|
||||
|
||||
_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 imageCreateInfo = new ImageViewCreateInfo()
|
||||
var imageCreateInfo = new ImageViewCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageViewCreateInfo,
|
||||
Image = swapchainImage,
|
||||
ViewType = ImageViewType.Type2D,
|
||||
Format = format,
|
||||
Components = componentMapping,
|
||||
SubresourceRange = subresourceRange
|
||||
SubresourceRange = subresourceRange,
|
||||
};
|
||||
|
||||
_gd.Api.CreateImageView(_device, imageCreateInfo, null, out var imageView).ThrowOnError();
|
||||
@ -234,13 +234,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
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)
|
||||
@ -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 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 dstPaddingX = (_width - dstWidth) / 2;
|
||||
int dstPaddingX = (_width - dstWidth) / 2;
|
||||
int dstPaddingY = (_height - dstHeight) / 2;
|
||||
|
||||
int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX;
|
||||
@ -413,7 +411,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
Result result;
|
||||
|
||||
var presentInfo = new PresentInfoKHR()
|
||||
var presentInfo = new PresentInfoKHR
|
||||
{
|
||||
SType = StructureType.PresentInfoKhr,
|
||||
WaitSemaphoreCount = 1,
|
||||
@ -421,7 +419,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SwapchainCount = 1,
|
||||
PSwapchains = &swapchain,
|
||||
PImageIndices = &nextImage,
|
||||
PResults = &result
|
||||
PResults = &result,
|
||||
};
|
||||
|
||||
lock (_gd.QueueLock)
|
||||
@ -529,7 +527,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ColorBit, 0, 1, 0, 1);
|
||||
|
||||
var barrier = new ImageMemoryBarrier()
|
||||
var barrier = new ImageMemoryBarrier
|
||||
{
|
||||
SType = StructureType.ImageMemoryBarrier,
|
||||
SrcAccessMask = srcAccess,
|
||||
@ -539,7 +537,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
Image = image,
|
||||
SubresourceRange = subresourceRange
|
||||
SubresourceRange = subresourceRange,
|
||||
};
|
||||
|
||||
_gd.Api.CmdPipelineBarrier(
|
||||
|
@ -3,7 +3,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal abstract class WindowBase: IWindow
|
||||
internal abstract class WindowBase : IWindow
|
||||
{
|
||||
public bool ScreenCaptureRequested { get; set; }
|
||||
|
||||
@ -15,4 +15,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public abstract void SetScalingFilter(ScalingFilter scalerType);
|
||||
public abstract void SetScalingFilterLevel(float scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user