0
0
Fork 0

[Ryujinx.Graphics.Vulkan] Address dotnet-format issues (#5378)

* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Silence dotnet format IDE0060 warnings

* Silence dotnet format IDE0059 warnings

* Address dotnet format CA1816 warnings

* Fix new dotnet-format issues after rebase

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format style after rebase

* Run dotnet format analyzers after rebase

* Run dotnet format style after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Disable 'prefer switch expression' rule

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Run dotnet format after rebase

* Address IDE0251 warnings

* Address a few disabled IDE0060 warnings

* Silence IDE0060 in .editorconfig

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix naming rule violations

* Remove redundant code

* Rename generics

* Address review feedback

* Remove SetOrigin
This commit is contained in:
TSRBerry 2023-07-01 12:31:42 +02:00 committed by GitHub
parent 12c5f6ee89
commit 801b71a128
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1134 additions and 1230 deletions

View file

@ -8,16 +8,16 @@ namespace Ryujinx.Graphics.Vulkan
internal class AutoFlushCounter
{
// 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})");

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -7,4 +7,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
const int LocalGroupSize = 64;
TextureView Run(TextureView view, CommandBufferScoped cbs, int width, int height);
}
}
}

View file

@ -17,4 +17,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
Extent2D source,
Extent2D destination);
}
}
}

View file

@ -12,4 +12,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
public float Width;
public float Height;
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -30,4 +30,4 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
vkSetMoltenVKConfigurationMVK(IntPtr.Zero, config, configSize);
}
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,4 +19,4 @@ namespace Ryujinx.Graphics.Vulkan
Access = access;
}
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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