Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
801b71a128 | ||
|
12c5f6ee89 | ||
|
79a1314ee4 |
@@ -7,15 +7,13 @@ namespace Ryujinx.Cpu
|
||||
{
|
||||
public class AddressSpace : IDisposable
|
||||
{
|
||||
private const ulong PageSize = 0x1000;
|
||||
|
||||
private const int DefaultBlockAlignment = 1 << 20;
|
||||
|
||||
private enum MappingType : byte
|
||||
{
|
||||
None,
|
||||
Private,
|
||||
Shared
|
||||
Shared,
|
||||
}
|
||||
|
||||
private class Mapping : IntrusiveRedBlackTreeNode<Mapping>, IComparable<Mapping>
|
||||
@@ -37,7 +35,7 @@ namespace Ryujinx.Cpu
|
||||
ulong leftSize = splitAddress - Address;
|
||||
ulong rightSize = EndAddress - splitAddress;
|
||||
|
||||
Mapping left = new Mapping(Address, leftSize, Type);
|
||||
Mapping left = new(Address, leftSize, Type);
|
||||
|
||||
Address = splitAddress;
|
||||
Size = rightSize;
|
||||
@@ -93,7 +91,7 @@ namespace Ryujinx.Cpu
|
||||
|
||||
(var leftAllocation, PrivateAllocation) = PrivateAllocation.Split(leftSize);
|
||||
|
||||
PrivateMapping left = new PrivateMapping(Address, leftSize, leftAllocation);
|
||||
PrivateMapping left = new(Address, leftSize, leftAllocation);
|
||||
|
||||
Address = splitAddress;
|
||||
Size = rightSize;
|
||||
@@ -181,7 +179,7 @@ namespace Ryujinx.Cpu
|
||||
{
|
||||
addressSpace = null;
|
||||
|
||||
MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
|
||||
const MemoryAllocationFlags asFlags = MemoryAllocationFlags.Reserve | MemoryAllocationFlags.ViewCompatible;
|
||||
|
||||
ulong minAddressSpaceSize = Math.Min(asSize, 1UL << 36);
|
||||
|
||||
@@ -391,8 +389,6 @@ namespace Ryujinx.Cpu
|
||||
ulong vaAligned = BitUtils.AlignDown(va, alignment);
|
||||
ulong endAddressAligned = BitUtils.AlignUp(endAddress, alignment);
|
||||
|
||||
ulong sizeAligned = endAddressAligned - vaAligned;
|
||||
|
||||
PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default));
|
||||
|
||||
for (; map != null; map = map.Successor)
|
||||
@@ -436,8 +432,6 @@ namespace Ryujinx.Cpu
|
||||
return;
|
||||
}
|
||||
|
||||
ulong alignedSize = endAddressAligned - vaAligned;
|
||||
|
||||
PrivateMapping map = _privateTree.GetNode(new PrivateMapping(va, 1UL, default));
|
||||
|
||||
for (; map != null; map = map.Successor)
|
||||
@@ -495,9 +489,11 @@ namespace Ryujinx.Cpu
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
_privateMemoryAllocator?.Dispose();
|
||||
Base.Dispose();
|
||||
Mirror.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -42,6 +42,6 @@ namespace Ryujinx.Cpu.AppleHv.Arm
|
||||
WatchpointSameEl = 0b110101,
|
||||
BkptAarch32 = 0b111000,
|
||||
VectorCatchAarch32 = 0b111010,
|
||||
BrkAarch64 = 0b111100
|
||||
BrkAarch64 = 0b111100,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
public class DummyDiskCacheLoadState : IDiskCacheLoadState
|
||||
{
|
||||
#pragma warning disable CS0067
|
||||
#pragma warning disable CS0067 // The event is never used
|
||||
/// <inheritdoc/>
|
||||
public event Action<LoadState, int, int> StateChanged;
|
||||
#pragma warning restore CS0067
|
||||
@@ -14,4 +14,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,18 +18,16 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
private const ulong AllocationGranule = 1UL << 14;
|
||||
|
||||
private readonly ulong _asBase;
|
||||
private readonly ulong _asSize;
|
||||
private readonly ulong _backingSize;
|
||||
|
||||
private readonly HvAddressSpaceRange _userRange;
|
||||
private readonly HvAddressSpaceRange _kernelRange;
|
||||
|
||||
private MemoryBlock _kernelCodeBlock;
|
||||
private readonly MemoryBlock _kernelCodeBlock;
|
||||
|
||||
public HvAddressSpace(MemoryBlock backingMemory, ulong asSize)
|
||||
{
|
||||
(_asBase, var ipaAllocator) = HvVm.CreateAddressSpace(backingMemory);
|
||||
_asSize = asSize;
|
||||
_backingSize = backingMemory.Size;
|
||||
|
||||
_userRange = new HvAddressSpaceRange(ipaAllocator);
|
||||
@@ -58,20 +56,20 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
_kernelCodeBlock.Write(KernelRegionEretOffset, 0xD69F03E0u); // ERET
|
||||
|
||||
ulong kernelCodePa = ipaAllocator.Allocate(AllocationGranule);
|
||||
HvApi.hv_vm_map((ulong)_kernelCodeBlock.Pointer, kernelCodePa, AllocationGranule, hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_EXEC).ThrowOnError();
|
||||
HvApi.hv_vm_map((ulong)_kernelCodeBlock.Pointer, kernelCodePa, AllocationGranule, HvMemoryFlags.Read | HvMemoryFlags.Exec).ThrowOnError();
|
||||
|
||||
_kernelRange.Map(KernelRegionCodeOffset, kernelCodePa, KernelRegionCodeSize, ApFlags.UserNoneKernelReadExecute);
|
||||
}
|
||||
|
||||
public void InitializeMmu(ulong vcpu)
|
||||
{
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_VBAR_EL1, KernelRegionBase + KernelRegionCodeOffset);
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.VBAR_EL1, KernelRegionBase + KernelRegionCodeOffset);
|
||||
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TTBR0_EL1, _userRange.GetIpaBase());
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TTBR1_EL1, _kernelRange.GetIpaBase());
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_MAIR_EL1, 0xffUL);
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_TCR_EL1, 0x00000011B5193519UL);
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_SCTLR_EL1, 0x0000000034D5D925UL);
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TTBR0_EL1, _userRange.GetIpaBase());
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TTBR1_EL1, _kernelRange.GetIpaBase());
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.MAIR_EL1, 0xffUL);
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.TCR_EL1, 0x00000011B5193519UL);
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu, HvSysReg.SCTLR_EL1, 0x0000000034D5D925UL);
|
||||
}
|
||||
|
||||
public bool GetAndClearUserTlbInvalidationPending()
|
||||
@@ -115,7 +113,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
MemoryPermission.ReadAndWrite => ApFlags.UserReadWriteKernelReadWrite,
|
||||
MemoryPermission.ReadAndExecute => ApFlags.UserReadExecuteKernelRead,
|
||||
MemoryPermission.ReadWriteExecute => ApFlags.UserReadWriteExecuteKernelReadWrite,
|
||||
_ => throw new ArgumentException($"Permission \"{permission}\" is invalid.")
|
||||
_ => throw new ArgumentException($"Permission \"{permission}\" is invalid."),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -126,4 +124,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
HvVm.DestroyAddressSpace(_asBase, _backingSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
ulong size = (ulong)count * sizeof(ulong);
|
||||
Allocation = blockAllocator.Allocate(size, PageSize);
|
||||
|
||||
AsSpan().Fill(0UL);
|
||||
AsSpan().Clear();
|
||||
|
||||
if (hasNext)
|
||||
{
|
||||
@@ -42,7 +42,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe Span<ulong> AsSpan()
|
||||
public Span<ulong> AsSpan()
|
||||
{
|
||||
return MemoryMarshal.Cast<byte, ulong>(Allocation.Memory.GetSpan(Allocation.Offset, (int)Allocation.Size));
|
||||
}
|
||||
@@ -52,12 +52,10 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
private int _tlbInvalidationPending;
|
||||
|
||||
private readonly HvIpaAllocator _ipaAllocator;
|
||||
private readonly HvMemoryBlockAllocator _blockAllocator;
|
||||
|
||||
public HvAddressSpaceRange(HvIpaAllocator ipaAllocator)
|
||||
{
|
||||
_ipaAllocator = ipaAllocator;
|
||||
_blockAllocator = new HvMemoryBlockAllocator(ipaAllocator, (int)AllocationGranule);
|
||||
}
|
||||
|
||||
@@ -129,7 +127,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
ulong endVa = (va + size + PageMask) & ~((ulong)PageMask);
|
||||
va &= ~((ulong)PageMask);
|
||||
|
||||
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth);
|
||||
(ulong blockSize, _) = GetBlockSizeAndShift(depth);
|
||||
|
||||
while (va < endVa)
|
||||
{
|
||||
@@ -138,7 +136,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
int l = (int)(va >> (PageBits + (2 - depth) * LevelBits)) & LevelMask;
|
||||
|
||||
PtLevel nextTable = level.Next != null ? level.Next[l] : null;
|
||||
PtLevel nextTable = level.Next?[l];
|
||||
|
||||
if (nextTable != null)
|
||||
{
|
||||
@@ -190,7 +188,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
ulong endVa = (va + size + PageSize - 1) & ~((ulong)PageSize - 1);
|
||||
va &= ~((ulong)PageSize - 1);
|
||||
|
||||
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth);
|
||||
(ulong blockSize, _) = GetBlockSizeAndShift(depth);
|
||||
|
||||
while (va < endVa)
|
||||
{
|
||||
@@ -204,7 +202,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
// First check if the region is mapped.
|
||||
if ((pte & 3) != 0)
|
||||
{
|
||||
PtLevel nextTable = level.Next != null ? level.Next[l] : null;
|
||||
PtLevel nextTable = level.Next?[l];
|
||||
|
||||
if (nextTable != null)
|
||||
{
|
||||
@@ -240,10 +238,10 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
pte &= ~3UL;
|
||||
pte |= (depth == 2 ? 3UL : 1UL);
|
||||
|
||||
PtLevel level = new PtLevel(_blockAllocator, LevelCount, depth < 2);
|
||||
PtLevel level = new(_blockAllocator, LevelCount, depth < 2);
|
||||
Span<ulong> currentLevel = level.AsSpan();
|
||||
|
||||
(ulong blockSize, int blockShift) = GetBlockSizeAndShift(depth);
|
||||
(_, int blockShift) = GetBlockSizeAndShift(depth);
|
||||
|
||||
// Fill in the blocks.
|
||||
for (int i = 0; i < LevelCount; i++)
|
||||
@@ -334,7 +332,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
if ((currentTable[index] & 1) == 0)
|
||||
{
|
||||
PtLevel nextLevel = new PtLevel(_blockAllocator, LevelCount, hasNext);
|
||||
PtLevel nextLevel = new(_blockAllocator, LevelCount, hasNext);
|
||||
|
||||
currentTable[index] = (nextLevel.Address & ~(ulong)PageMask) | 3UL;
|
||||
level.Next[index] = nextLevel;
|
||||
@@ -347,7 +345,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteBlock(PtLevel level, int index, int depth, ulong pa, ulong attr)
|
||||
private static void WriteBlock(PtLevel level, int index, int depth, ulong pa, ulong attr)
|
||||
{
|
||||
Span<ulong> currentTable = level.AsSpan();
|
||||
|
||||
@@ -367,4 +365,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
_blockAllocator.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,245 +1,244 @@
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
struct hv_vcpu_exit_exception_t
|
||||
struct HvVcpuExitException
|
||||
{
|
||||
#pragma warning disable CS0649
|
||||
public ulong syndrome;
|
||||
public ulong virtual_address;
|
||||
public ulong physical_address;
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public ulong Syndrome;
|
||||
public ulong VirtualAddress;
|
||||
public ulong PhysicalAddress;
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
struct hv_vcpu_exit_t
|
||||
struct HvVcpuExit
|
||||
{
|
||||
#pragma warning disable CS0649
|
||||
public uint reason;
|
||||
public hv_vcpu_exit_exception_t exception;
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Reason;
|
||||
public HvVcpuExitException Exception;
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
enum hv_reg_t : uint
|
||||
enum HvReg : uint
|
||||
{
|
||||
HV_REG_X0,
|
||||
HV_REG_X1,
|
||||
HV_REG_X2,
|
||||
HV_REG_X3,
|
||||
HV_REG_X4,
|
||||
HV_REG_X5,
|
||||
HV_REG_X6,
|
||||
HV_REG_X7,
|
||||
HV_REG_X8,
|
||||
HV_REG_X9,
|
||||
HV_REG_X10,
|
||||
HV_REG_X11,
|
||||
HV_REG_X12,
|
||||
HV_REG_X13,
|
||||
HV_REG_X14,
|
||||
HV_REG_X15,
|
||||
HV_REG_X16,
|
||||
HV_REG_X17,
|
||||
HV_REG_X18,
|
||||
HV_REG_X19,
|
||||
HV_REG_X20,
|
||||
HV_REG_X21,
|
||||
HV_REG_X22,
|
||||
HV_REG_X23,
|
||||
HV_REG_X24,
|
||||
HV_REG_X25,
|
||||
HV_REG_X26,
|
||||
HV_REG_X27,
|
||||
HV_REG_X28,
|
||||
HV_REG_X29,
|
||||
HV_REG_FP = HV_REG_X29,
|
||||
HV_REG_X30,
|
||||
HV_REG_LR = HV_REG_X30,
|
||||
HV_REG_PC,
|
||||
HV_REG_FPCR,
|
||||
HV_REG_FPSR,
|
||||
HV_REG_CPSR,
|
||||
X0,
|
||||
X1,
|
||||
X2,
|
||||
X3,
|
||||
X4,
|
||||
X5,
|
||||
X6,
|
||||
X7,
|
||||
X8,
|
||||
X9,
|
||||
X10,
|
||||
X11,
|
||||
X12,
|
||||
X13,
|
||||
X14,
|
||||
X15,
|
||||
X16,
|
||||
X17,
|
||||
X18,
|
||||
X19,
|
||||
X20,
|
||||
X21,
|
||||
X22,
|
||||
X23,
|
||||
X24,
|
||||
X25,
|
||||
X26,
|
||||
X27,
|
||||
X28,
|
||||
X29,
|
||||
FP = X29,
|
||||
X30,
|
||||
LR = X30,
|
||||
PC,
|
||||
FPCR,
|
||||
FPSR,
|
||||
CPSR,
|
||||
}
|
||||
|
||||
enum hv_simd_fp_reg_t : uint
|
||||
enum HvSimdFPReg : uint
|
||||
{
|
||||
HV_SIMD_FP_REG_Q0,
|
||||
HV_SIMD_FP_REG_Q1,
|
||||
HV_SIMD_FP_REG_Q2,
|
||||
HV_SIMD_FP_REG_Q3,
|
||||
HV_SIMD_FP_REG_Q4,
|
||||
HV_SIMD_FP_REG_Q5,
|
||||
HV_SIMD_FP_REG_Q6,
|
||||
HV_SIMD_FP_REG_Q7,
|
||||
HV_SIMD_FP_REG_Q8,
|
||||
HV_SIMD_FP_REG_Q9,
|
||||
HV_SIMD_FP_REG_Q10,
|
||||
HV_SIMD_FP_REG_Q11,
|
||||
HV_SIMD_FP_REG_Q12,
|
||||
HV_SIMD_FP_REG_Q13,
|
||||
HV_SIMD_FP_REG_Q14,
|
||||
HV_SIMD_FP_REG_Q15,
|
||||
HV_SIMD_FP_REG_Q16,
|
||||
HV_SIMD_FP_REG_Q17,
|
||||
HV_SIMD_FP_REG_Q18,
|
||||
HV_SIMD_FP_REG_Q19,
|
||||
HV_SIMD_FP_REG_Q20,
|
||||
HV_SIMD_FP_REG_Q21,
|
||||
HV_SIMD_FP_REG_Q22,
|
||||
HV_SIMD_FP_REG_Q23,
|
||||
HV_SIMD_FP_REG_Q24,
|
||||
HV_SIMD_FP_REG_Q25,
|
||||
HV_SIMD_FP_REG_Q26,
|
||||
HV_SIMD_FP_REG_Q27,
|
||||
HV_SIMD_FP_REG_Q28,
|
||||
HV_SIMD_FP_REG_Q29,
|
||||
HV_SIMD_FP_REG_Q30,
|
||||
HV_SIMD_FP_REG_Q31,
|
||||
Q0,
|
||||
Q1,
|
||||
Q2,
|
||||
Q3,
|
||||
Q4,
|
||||
Q5,
|
||||
Q6,
|
||||
Q7,
|
||||
Q8,
|
||||
Q9,
|
||||
Q10,
|
||||
Q11,
|
||||
Q12,
|
||||
Q13,
|
||||
Q14,
|
||||
Q15,
|
||||
Q16,
|
||||
Q17,
|
||||
Q18,
|
||||
Q19,
|
||||
Q20,
|
||||
Q21,
|
||||
Q22,
|
||||
Q23,
|
||||
Q24,
|
||||
Q25,
|
||||
Q26,
|
||||
Q27,
|
||||
Q28,
|
||||
Q29,
|
||||
Q30,
|
||||
Q31,
|
||||
}
|
||||
|
||||
enum hv_sys_reg_t : ushort
|
||||
enum HvSysReg : ushort
|
||||
{
|
||||
HV_SYS_REG_DBGBVR0_EL1 = 0x8004,
|
||||
HV_SYS_REG_DBGBCR0_EL1 = 0x8005,
|
||||
HV_SYS_REG_DBGWVR0_EL1 = 0x8006,
|
||||
HV_SYS_REG_DBGWCR0_EL1 = 0x8007,
|
||||
HV_SYS_REG_DBGBVR1_EL1 = 0x800c,
|
||||
HV_SYS_REG_DBGBCR1_EL1 = 0x800d,
|
||||
HV_SYS_REG_DBGWVR1_EL1 = 0x800e,
|
||||
HV_SYS_REG_DBGWCR1_EL1 = 0x800f,
|
||||
HV_SYS_REG_MDCCINT_EL1 = 0x8010,
|
||||
HV_SYS_REG_MDSCR_EL1 = 0x8012,
|
||||
HV_SYS_REG_DBGBVR2_EL1 = 0x8014,
|
||||
HV_SYS_REG_DBGBCR2_EL1 = 0x8015,
|
||||
HV_SYS_REG_DBGWVR2_EL1 = 0x8016,
|
||||
HV_SYS_REG_DBGWCR2_EL1 = 0x8017,
|
||||
HV_SYS_REG_DBGBVR3_EL1 = 0x801c,
|
||||
HV_SYS_REG_DBGBCR3_EL1 = 0x801d,
|
||||
HV_SYS_REG_DBGWVR3_EL1 = 0x801e,
|
||||
HV_SYS_REG_DBGWCR3_EL1 = 0x801f,
|
||||
HV_SYS_REG_DBGBVR4_EL1 = 0x8024,
|
||||
HV_SYS_REG_DBGBCR4_EL1 = 0x8025,
|
||||
HV_SYS_REG_DBGWVR4_EL1 = 0x8026,
|
||||
HV_SYS_REG_DBGWCR4_EL1 = 0x8027,
|
||||
HV_SYS_REG_DBGBVR5_EL1 = 0x802c,
|
||||
HV_SYS_REG_DBGBCR5_EL1 = 0x802d,
|
||||
HV_SYS_REG_DBGWVR5_EL1 = 0x802e,
|
||||
HV_SYS_REG_DBGWCR5_EL1 = 0x802f,
|
||||
HV_SYS_REG_DBGBVR6_EL1 = 0x8034,
|
||||
HV_SYS_REG_DBGBCR6_EL1 = 0x8035,
|
||||
HV_SYS_REG_DBGWVR6_EL1 = 0x8036,
|
||||
HV_SYS_REG_DBGWCR6_EL1 = 0x8037,
|
||||
HV_SYS_REG_DBGBVR7_EL1 = 0x803c,
|
||||
HV_SYS_REG_DBGBCR7_EL1 = 0x803d,
|
||||
HV_SYS_REG_DBGWVR7_EL1 = 0x803e,
|
||||
HV_SYS_REG_DBGWCR7_EL1 = 0x803f,
|
||||
HV_SYS_REG_DBGBVR8_EL1 = 0x8044,
|
||||
HV_SYS_REG_DBGBCR8_EL1 = 0x8045,
|
||||
HV_SYS_REG_DBGWVR8_EL1 = 0x8046,
|
||||
HV_SYS_REG_DBGWCR8_EL1 = 0x8047,
|
||||
HV_SYS_REG_DBGBVR9_EL1 = 0x804c,
|
||||
HV_SYS_REG_DBGBCR9_EL1 = 0x804d,
|
||||
HV_SYS_REG_DBGWVR9_EL1 = 0x804e,
|
||||
HV_SYS_REG_DBGWCR9_EL1 = 0x804f,
|
||||
HV_SYS_REG_DBGBVR10_EL1 = 0x8054,
|
||||
HV_SYS_REG_DBGBCR10_EL1 = 0x8055,
|
||||
HV_SYS_REG_DBGWVR10_EL1 = 0x8056,
|
||||
HV_SYS_REG_DBGWCR10_EL1 = 0x8057,
|
||||
HV_SYS_REG_DBGBVR11_EL1 = 0x805c,
|
||||
HV_SYS_REG_DBGBCR11_EL1 = 0x805d,
|
||||
HV_SYS_REG_DBGWVR11_EL1 = 0x805e,
|
||||
HV_SYS_REG_DBGWCR11_EL1 = 0x805f,
|
||||
HV_SYS_REG_DBGBVR12_EL1 = 0x8064,
|
||||
HV_SYS_REG_DBGBCR12_EL1 = 0x8065,
|
||||
HV_SYS_REG_DBGWVR12_EL1 = 0x8066,
|
||||
HV_SYS_REG_DBGWCR12_EL1 = 0x8067,
|
||||
HV_SYS_REG_DBGBVR13_EL1 = 0x806c,
|
||||
HV_SYS_REG_DBGBCR13_EL1 = 0x806d,
|
||||
HV_SYS_REG_DBGWVR13_EL1 = 0x806e,
|
||||
HV_SYS_REG_DBGWCR13_EL1 = 0x806f,
|
||||
HV_SYS_REG_DBGBVR14_EL1 = 0x8074,
|
||||
HV_SYS_REG_DBGBCR14_EL1 = 0x8075,
|
||||
HV_SYS_REG_DBGWVR14_EL1 = 0x8076,
|
||||
HV_SYS_REG_DBGWCR14_EL1 = 0x8077,
|
||||
HV_SYS_REG_DBGBVR15_EL1 = 0x807c,
|
||||
HV_SYS_REG_DBGBCR15_EL1 = 0x807d,
|
||||
HV_SYS_REG_DBGWVR15_EL1 = 0x807e,
|
||||
HV_SYS_REG_DBGWCR15_EL1 = 0x807f,
|
||||
HV_SYS_REG_MIDR_EL1 = 0xc000,
|
||||
HV_SYS_REG_MPIDR_EL1 = 0xc005,
|
||||
HV_SYS_REG_ID_AA64PFR0_EL1 = 0xc020,
|
||||
HV_SYS_REG_ID_AA64PFR1_EL1 = 0xc021,
|
||||
HV_SYS_REG_ID_AA64DFR0_EL1 = 0xc028,
|
||||
HV_SYS_REG_ID_AA64DFR1_EL1 = 0xc029,
|
||||
HV_SYS_REG_ID_AA64ISAR0_EL1 = 0xc030,
|
||||
HV_SYS_REG_ID_AA64ISAR1_EL1 = 0xc031,
|
||||
HV_SYS_REG_ID_AA64MMFR0_EL1 = 0xc038,
|
||||
HV_SYS_REG_ID_AA64MMFR1_EL1 = 0xc039,
|
||||
HV_SYS_REG_ID_AA64MMFR2_EL1 = 0xc03a,
|
||||
HV_SYS_REG_SCTLR_EL1 = 0xc080,
|
||||
HV_SYS_REG_CPACR_EL1 = 0xc082,
|
||||
HV_SYS_REG_TTBR0_EL1 = 0xc100,
|
||||
HV_SYS_REG_TTBR1_EL1 = 0xc101,
|
||||
HV_SYS_REG_TCR_EL1 = 0xc102,
|
||||
HV_SYS_REG_APIAKEYLO_EL1 = 0xc108,
|
||||
HV_SYS_REG_APIAKEYHI_EL1 = 0xc109,
|
||||
HV_SYS_REG_APIBKEYLO_EL1 = 0xc10a,
|
||||
HV_SYS_REG_APIBKEYHI_EL1 = 0xc10b,
|
||||
HV_SYS_REG_APDAKEYLO_EL1 = 0xc110,
|
||||
HV_SYS_REG_APDAKEYHI_EL1 = 0xc111,
|
||||
HV_SYS_REG_APDBKEYLO_EL1 = 0xc112,
|
||||
HV_SYS_REG_APDBKEYHI_EL1 = 0xc113,
|
||||
HV_SYS_REG_APGAKEYLO_EL1 = 0xc118,
|
||||
HV_SYS_REG_APGAKEYHI_EL1 = 0xc119,
|
||||
HV_SYS_REG_SPSR_EL1 = 0xc200,
|
||||
HV_SYS_REG_ELR_EL1 = 0xc201,
|
||||
HV_SYS_REG_SP_EL0 = 0xc208,
|
||||
HV_SYS_REG_AFSR0_EL1 = 0xc288,
|
||||
HV_SYS_REG_AFSR1_EL1 = 0xc289,
|
||||
HV_SYS_REG_ESR_EL1 = 0xc290,
|
||||
HV_SYS_REG_FAR_EL1 = 0xc300,
|
||||
HV_SYS_REG_PAR_EL1 = 0xc3a0,
|
||||
HV_SYS_REG_MAIR_EL1 = 0xc510,
|
||||
HV_SYS_REG_AMAIR_EL1 = 0xc518,
|
||||
HV_SYS_REG_VBAR_EL1 = 0xc600,
|
||||
HV_SYS_REG_CONTEXTIDR_EL1 = 0xc681,
|
||||
HV_SYS_REG_TPIDR_EL1 = 0xc684,
|
||||
HV_SYS_REG_CNTKCTL_EL1 = 0xc708,
|
||||
HV_SYS_REG_CSSELR_EL1 = 0xd000,
|
||||
HV_SYS_REG_TPIDR_EL0 = 0xde82,
|
||||
HV_SYS_REG_TPIDRRO_EL0 = 0xde83,
|
||||
HV_SYS_REG_CNTV_CTL_EL0 = 0xdf19,
|
||||
HV_SYS_REG_CNTV_CVAL_EL0 = 0xdf1a,
|
||||
HV_SYS_REG_SP_EL1 = 0xe208,
|
||||
DBGBVR0_EL1 = 0x8004,
|
||||
DBGBCR0_EL1 = 0x8005,
|
||||
DBGWVR0_EL1 = 0x8006,
|
||||
DBGWCR0_EL1 = 0x8007,
|
||||
DBGBVR1_EL1 = 0x800c,
|
||||
DBGBCR1_EL1 = 0x800d,
|
||||
DBGWVR1_EL1 = 0x800e,
|
||||
DBGWCR1_EL1 = 0x800f,
|
||||
MDCCINT_EL1 = 0x8010,
|
||||
MDSCR_EL1 = 0x8012,
|
||||
DBGBVR2_EL1 = 0x8014,
|
||||
DBGBCR2_EL1 = 0x8015,
|
||||
DBGWVR2_EL1 = 0x8016,
|
||||
DBGWCR2_EL1 = 0x8017,
|
||||
DBGBVR3_EL1 = 0x801c,
|
||||
DBGBCR3_EL1 = 0x801d,
|
||||
DBGWVR3_EL1 = 0x801e,
|
||||
DBGWCR3_EL1 = 0x801f,
|
||||
DBGBVR4_EL1 = 0x8024,
|
||||
DBGBCR4_EL1 = 0x8025,
|
||||
DBGWVR4_EL1 = 0x8026,
|
||||
DBGWCR4_EL1 = 0x8027,
|
||||
DBGBVR5_EL1 = 0x802c,
|
||||
DBGBCR5_EL1 = 0x802d,
|
||||
DBGWVR5_EL1 = 0x802e,
|
||||
DBGWCR5_EL1 = 0x802f,
|
||||
DBGBVR6_EL1 = 0x8034,
|
||||
DBGBCR6_EL1 = 0x8035,
|
||||
DBGWVR6_EL1 = 0x8036,
|
||||
DBGWCR6_EL1 = 0x8037,
|
||||
DBGBVR7_EL1 = 0x803c,
|
||||
DBGBCR7_EL1 = 0x803d,
|
||||
DBGWVR7_EL1 = 0x803e,
|
||||
DBGWCR7_EL1 = 0x803f,
|
||||
DBGBVR8_EL1 = 0x8044,
|
||||
DBGBCR8_EL1 = 0x8045,
|
||||
DBGWVR8_EL1 = 0x8046,
|
||||
DBGWCR8_EL1 = 0x8047,
|
||||
DBGBVR9_EL1 = 0x804c,
|
||||
DBGBCR9_EL1 = 0x804d,
|
||||
DBGWVR9_EL1 = 0x804e,
|
||||
DBGWCR9_EL1 = 0x804f,
|
||||
DBGBVR10_EL1 = 0x8054,
|
||||
DBGBCR10_EL1 = 0x8055,
|
||||
DBGWVR10_EL1 = 0x8056,
|
||||
DBGWCR10_EL1 = 0x8057,
|
||||
DBGBVR11_EL1 = 0x805c,
|
||||
DBGBCR11_EL1 = 0x805d,
|
||||
DBGWVR11_EL1 = 0x805e,
|
||||
DBGWCR11_EL1 = 0x805f,
|
||||
DBGBVR12_EL1 = 0x8064,
|
||||
DBGBCR12_EL1 = 0x8065,
|
||||
DBGWVR12_EL1 = 0x8066,
|
||||
DBGWCR12_EL1 = 0x8067,
|
||||
DBGBVR13_EL1 = 0x806c,
|
||||
DBGBCR13_EL1 = 0x806d,
|
||||
DBGWVR13_EL1 = 0x806e,
|
||||
DBGWCR13_EL1 = 0x806f,
|
||||
DBGBVR14_EL1 = 0x8074,
|
||||
DBGBCR14_EL1 = 0x8075,
|
||||
DBGWVR14_EL1 = 0x8076,
|
||||
DBGWCR14_EL1 = 0x8077,
|
||||
DBGBVR15_EL1 = 0x807c,
|
||||
DBGBCR15_EL1 = 0x807d,
|
||||
DBGWVR15_EL1 = 0x807e,
|
||||
DBGWCR15_EL1 = 0x807f,
|
||||
MIDR_EL1 = 0xc000,
|
||||
MPIDR_EL1 = 0xc005,
|
||||
ID_AA64PFR0_EL1 = 0xc020,
|
||||
ID_AA64PFR1_EL1 = 0xc021,
|
||||
ID_AA64DFR0_EL1 = 0xc028,
|
||||
ID_AA64DFR1_EL1 = 0xc029,
|
||||
ID_AA64ISAR0_EL1 = 0xc030,
|
||||
ID_AA64ISAR1_EL1 = 0xc031,
|
||||
ID_AA64MMFR0_EL1 = 0xc038,
|
||||
ID_AA64MMFR1_EL1 = 0xc039,
|
||||
ID_AA64MMFR2_EL1 = 0xc03a,
|
||||
SCTLR_EL1 = 0xc080,
|
||||
CPACR_EL1 = 0xc082,
|
||||
TTBR0_EL1 = 0xc100,
|
||||
TTBR1_EL1 = 0xc101,
|
||||
TCR_EL1 = 0xc102,
|
||||
APIAKEYLO_EL1 = 0xc108,
|
||||
APIAKEYHI_EL1 = 0xc109,
|
||||
APIBKEYLO_EL1 = 0xc10a,
|
||||
APIBKEYHI_EL1 = 0xc10b,
|
||||
APDAKEYLO_EL1 = 0xc110,
|
||||
APDAKEYHI_EL1 = 0xc111,
|
||||
APDBKEYLO_EL1 = 0xc112,
|
||||
APDBKEYHI_EL1 = 0xc113,
|
||||
APGAKEYLO_EL1 = 0xc118,
|
||||
APGAKEYHI_EL1 = 0xc119,
|
||||
SPSR_EL1 = 0xc200,
|
||||
ELR_EL1 = 0xc201,
|
||||
SP_EL0 = 0xc208,
|
||||
AFSR0_EL1 = 0xc288,
|
||||
AFSR1_EL1 = 0xc289,
|
||||
ESR_EL1 = 0xc290,
|
||||
FAR_EL1 = 0xc300,
|
||||
PAR_EL1 = 0xc3a0,
|
||||
MAIR_EL1 = 0xc510,
|
||||
AMAIR_EL1 = 0xc518,
|
||||
VBAR_EL1 = 0xc600,
|
||||
CONTEXTIDR_EL1 = 0xc681,
|
||||
TPIDR_EL1 = 0xc684,
|
||||
CNTKCTL_EL1 = 0xc708,
|
||||
CSSELR_EL1 = 0xd000,
|
||||
TPIDR_EL0 = 0xde82,
|
||||
TPIDRRO_EL0 = 0xde83,
|
||||
CNTV_CTL_EL0 = 0xdf19,
|
||||
CNTV_CVAL_EL0 = 0xdf1a,
|
||||
SP_EL1 = 0xe208,
|
||||
}
|
||||
|
||||
enum hv_memory_flags_t : ulong
|
||||
enum HvMemoryFlags : ulong
|
||||
{
|
||||
HV_MEMORY_READ = 1UL << 0,
|
||||
HV_MEMORY_WRITE = 1UL << 1,
|
||||
HV_MEMORY_EXEC = 1UL << 2
|
||||
Read = 1UL << 0,
|
||||
Write = 1UL << 1,
|
||||
Exec = 1UL << 2,
|
||||
}
|
||||
|
||||
enum hv_result_t : uint
|
||||
enum HvResult : uint
|
||||
{
|
||||
HV_SUCCESS = 0,
|
||||
HV_ERROR = 0xfae94001,
|
||||
HV_BUSY = 0xfae94002,
|
||||
HV_BAD_ARGUMENT = 0xfae94003,
|
||||
HV_NO_RESOURCES = 0xfae94005,
|
||||
HV_NO_DEVICE = 0xfae94006,
|
||||
HV_DENIED = 0xfae94007,
|
||||
HV_UNSUPPORTED = 0xfae9400f
|
||||
Success = 0,
|
||||
Error = 0xfae94001,
|
||||
Busy = 0xfae94002,
|
||||
BadArgument = 0xfae94003,
|
||||
NoResources = 0xfae94005,
|
||||
NoDevice = 0xfae94006,
|
||||
Denied = 0xfae94007,
|
||||
Unsupported = 0xfae9400f,
|
||||
}
|
||||
|
||||
enum hv_interrupt_type_t : uint
|
||||
enum HvInterruptType : uint
|
||||
{
|
||||
HV_INTERRUPT_TYPE_IRQ,
|
||||
HV_INTERRUPT_TYPE_FIQ
|
||||
IRQ,
|
||||
FIQ,
|
||||
}
|
||||
|
||||
struct hv_simd_fp_uchar16_t
|
||||
struct HvSimdFPUchar16
|
||||
{
|
||||
public ulong Low;
|
||||
public ulong High;
|
||||
@@ -247,9 +246,9 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
static class HvResultExtensions
|
||||
{
|
||||
public static void ThrowOnError(this hv_result_t result)
|
||||
public static void ThrowOnError(this HvResult result)
|
||||
{
|
||||
if (result != hv_result_t.HV_SUCCESS)
|
||||
if (result != HvResult.Success)
|
||||
{
|
||||
throw new Exception($"Unexpected result \"{result}\".");
|
||||
}
|
||||
@@ -261,60 +260,60 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
public const string LibraryName = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor";
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vm_get_max_vcpu_count(out uint max_vcpu_count);
|
||||
public static partial HvResult hv_vm_get_max_vcpu_count(out uint max_vcpu_count);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vm_create(IntPtr config);
|
||||
public static partial HvResult hv_vm_create(IntPtr config);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vm_destroy();
|
||||
public static partial HvResult hv_vm_destroy();
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vm_map(ulong addr, ulong ipa, ulong size, hv_memory_flags_t flags);
|
||||
public static partial HvResult hv_vm_map(ulong addr, ulong ipa, ulong size, HvMemoryFlags flags);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vm_unmap(ulong ipa, ulong size);
|
||||
public static partial HvResult hv_vm_unmap(ulong ipa, ulong size);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vm_protect(ulong ipa, ulong size, hv_memory_flags_t flags);
|
||||
public static partial HvResult hv_vm_protect(ulong ipa, ulong size, HvMemoryFlags flags);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public unsafe static partial hv_result_t hv_vcpu_create(out ulong vcpu, ref hv_vcpu_exit_t* exit, IntPtr config);
|
||||
public unsafe static partial HvResult hv_vcpu_create(out ulong vcpu, ref HvVcpuExit* exit, IntPtr config);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public unsafe static partial hv_result_t hv_vcpu_destroy(ulong vcpu);
|
||||
public unsafe static partial HvResult hv_vcpu_destroy(ulong vcpu);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_run(ulong vcpu);
|
||||
public static partial HvResult hv_vcpu_run(ulong vcpu);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpus_exit(ref ulong vcpus, uint vcpu_count);
|
||||
public static partial HvResult hv_vcpus_exit(ref ulong vcpus, uint vcpu_count);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked);
|
||||
public static partial HvResult hv_vcpu_set_vtimer_mask(ulong vcpu, [MarshalAs(UnmanagedType.Bool)] bool vtimer_is_masked);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_get_reg(ulong vcpu, hv_reg_t reg, out ulong value);
|
||||
public static partial HvResult hv_vcpu_get_reg(ulong vcpu, HvReg reg, out ulong value);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_set_reg(ulong vcpu, hv_reg_t reg, ulong value);
|
||||
public static partial HvResult hv_vcpu_set_reg(ulong vcpu, HvReg reg, ulong value);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_get_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, out hv_simd_fp_uchar16_t value);
|
||||
public static partial HvResult hv_vcpu_get_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, out HvSimdFPUchar16 value);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_set_simd_fp_reg(ulong vcpu, hv_simd_fp_reg_t reg, hv_simd_fp_uchar16_t value); // DO NOT USE DIRECTLY!
|
||||
public static partial HvResult hv_vcpu_set_simd_fp_reg(ulong vcpu, HvSimdFPReg reg, HvSimdFPUchar16 value); // DO NOT USE DIRECTLY!
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_get_sys_reg(ulong vcpu, hv_sys_reg_t reg, out ulong value);
|
||||
public static partial HvResult hv_vcpu_get_sys_reg(ulong vcpu, HvSysReg reg, out ulong value);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_set_sys_reg(ulong vcpu, hv_sys_reg_t reg, ulong value);
|
||||
public static partial HvResult hv_vcpu_set_sys_reg(ulong vcpu, HvSysReg reg, ulong value);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_get_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] out bool pending);
|
||||
public static partial HvResult hv_vcpu_get_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] out bool pending);
|
||||
|
||||
[LibraryImport(LibraryName, SetLastError = true)]
|
||||
public static partial hv_result_t hv_vcpu_set_pending_interrupt(ulong vcpu, hv_interrupt_type_t type, [MarshalAs(UnmanagedType.Bool)] bool pending);
|
||||
public static partial HvResult hv_vcpu_set_pending_interrupt(ulong vcpu, HvInterruptType type, [MarshalAs(UnmanagedType.Bool)] bool pending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using ARMeilleure.Memory;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
@@ -14,10 +13,6 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
_memoryManager = (HvMemoryManager)memory;
|
||||
}
|
||||
|
||||
private void UnmapHandler(ulong address, ulong size)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IExecutionContext CreateExecutionContext(ExceptionCallbacks exceptionCallbacks)
|
||||
{
|
||||
@@ -44,4 +39,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,4 +17,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
return new HvCpuContext(_tickSource, memoryManager, for64Bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -125,17 +125,17 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
HvVcpu vcpu = HvVcpuPool.Instance.Create(memoryManager.AddressSpace, _shadowContext, SwapContext);
|
||||
|
||||
HvApi.hv_vcpu_set_reg(vcpu.Handle, hv_reg_t.HV_REG_PC, address).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_reg(vcpu.Handle, HvReg.PC, address).ThrowOnError();
|
||||
|
||||
while (Running)
|
||||
{
|
||||
HvApi.hv_vcpu_run(vcpu.Handle).ThrowOnError();
|
||||
|
||||
uint reason = vcpu.ExitInfo->reason;
|
||||
uint reason = vcpu.ExitInfo->Reason;
|
||||
|
||||
if (reason == 1)
|
||||
{
|
||||
uint hvEsr = (uint)vcpu.ExitInfo->exception.syndrome;
|
||||
uint hvEsr = (uint)vcpu.ExitInfo->Exception.Syndrome;
|
||||
ExceptionClass hvEc = (ExceptionClass)(hvEsr >> 26);
|
||||
|
||||
if (hvEc != ExceptionClass.HvcAarch64)
|
||||
@@ -144,7 +144,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
}
|
||||
|
||||
address = SynchronousException(memoryManager, ref vcpu);
|
||||
HvApi.hv_vcpu_set_reg(vcpu.Handle, hv_reg_t.HV_REG_PC, address).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_reg(vcpu.Handle, HvReg.PC, address).ThrowOnError();
|
||||
}
|
||||
else if (reason == 0)
|
||||
{
|
||||
@@ -168,8 +168,8 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
ulong vcpuHandle = vcpu.Handle;
|
||||
|
||||
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, out ulong elr).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, out ulong esr).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError();
|
||||
|
||||
ExceptionClass ec = (ExceptionClass)((uint)esr >> 26);
|
||||
|
||||
@@ -180,7 +180,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
break;
|
||||
case ExceptionClass.TrappedMsrMrsSystem:
|
||||
InstructionTrap((uint)esr);
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, elr + 4UL).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.ELR_EL1, elr + 4UL).ThrowOnError();
|
||||
break;
|
||||
case ExceptionClass.SvcAarch64:
|
||||
ReturnToPool(vcpu);
|
||||
@@ -204,7 +204,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
}
|
||||
}
|
||||
|
||||
private void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr)
|
||||
private static void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr)
|
||||
{
|
||||
bool write = (esr & (1u << 6)) != 0;
|
||||
bool farValid = (esr & (1u << 10)) == 0;
|
||||
@@ -212,7 +212,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
if (farValid)
|
||||
{
|
||||
HvApi.hv_vcpu_get_sys_reg(vcpu, hv_sys_reg_t.HV_SYS_REG_FAR_EL1, out ulong far).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(vcpu, HvSysReg.FAR_EL1, out ulong far).ThrowOnError();
|
||||
|
||||
ulong size = 1UL << accessSizeLog2;
|
||||
|
||||
@@ -281,4 +281,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ using ARMeilleure.State;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
unsafe class HvExecutionContextShadow : IHvExecutionContext
|
||||
class HvExecutionContextShadow : IHvExecutionContext
|
||||
{
|
||||
public ulong Pc { get; set; }
|
||||
public ulong ElrEl1 { get; set; }
|
||||
@@ -56,4 +56,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,10 +8,10 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
class HvExecutionContextVcpu : IHvExecutionContext
|
||||
{
|
||||
private static MemoryBlock _setSimdFpRegFuncMem;
|
||||
private delegate hv_result_t SetSimdFpReg(ulong vcpu, hv_simd_fp_reg_t reg, in V128 value, IntPtr funcPtr);
|
||||
private static SetSimdFpReg _setSimdFpReg;
|
||||
private static IntPtr _setSimdFpRegNativePtr;
|
||||
private static readonly MemoryBlock _setSimdFpRegFuncMem;
|
||||
private delegate HvResult SetSimdFpReg(ulong vcpu, HvSimdFPReg reg, in V128 value, IntPtr funcPtr);
|
||||
private static readonly SetSimdFpReg _setSimdFpReg;
|
||||
private static readonly IntPtr _setSimdFpRegNativePtr;
|
||||
|
||||
static HvExecutionContextVcpu()
|
||||
{
|
||||
@@ -34,12 +34,12 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
get
|
||||
{
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_PC, out ulong pc).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.PC, out ulong pc).ThrowOnError();
|
||||
return pc;
|
||||
}
|
||||
set
|
||||
{
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_PC, value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.PC, value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,12 +47,12 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
get
|
||||
{
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, out ulong elr).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ELR_EL1, out ulong elr).ThrowOnError();
|
||||
return elr;
|
||||
}
|
||||
set
|
||||
{
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ELR_EL1, value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ELR_EL1, value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,12 +60,12 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
get
|
||||
{
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, out ulong esr).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.ESR_EL1, out ulong esr).ThrowOnError();
|
||||
return esr;
|
||||
}
|
||||
set
|
||||
{
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_ESR_EL1, value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.ESR_EL1, value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,12 +73,12 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
get
|
||||
{
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDR_EL0, out ulong tpidrEl0).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, out ulong tpidrEl0).ThrowOnError();
|
||||
return (long)tpidrEl0;
|
||||
}
|
||||
set
|
||||
{
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDR_EL0, (ulong)value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDR_EL0, (ulong)value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,12 +86,12 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
get
|
||||
{
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, out ulong tpidrroEl0).ThrowOnError();
|
||||
return (long)tpidrroEl0;
|
||||
}
|
||||
set
|
||||
{
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_TPIDRRO_EL0, (ulong)value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.TPIDRRO_EL0, (ulong)value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,12 +99,12 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
get
|
||||
{
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_CPSR, out ulong cpsr).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.CPSR, out ulong cpsr).ThrowOnError();
|
||||
return (uint)cpsr;
|
||||
}
|
||||
set
|
||||
{
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_CPSR, (ulong)value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.CPSR, (ulong)value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,12 +112,12 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
get
|
||||
{
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_FPCR, out ulong fpcr).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPCR, out ulong fpcr).ThrowOnError();
|
||||
return (uint)fpcr;
|
||||
}
|
||||
set
|
||||
{
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_FPCR, (ulong)value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPCR, (ulong)value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,16 +125,16 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
get
|
||||
{
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_FPSR, out ulong fpsr).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.FPSR, out ulong fpsr).ThrowOnError();
|
||||
return (uint)fpsr;
|
||||
}
|
||||
set
|
||||
{
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_FPSR, (ulong)value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.FPSR, (ulong)value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
private ulong _vcpu;
|
||||
private readonly ulong _vcpu;
|
||||
private int _interruptRequested;
|
||||
|
||||
public HvExecutionContextVcpu(ulong vcpu)
|
||||
@@ -146,12 +146,12 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
if (index == 31)
|
||||
{
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_SP_EL0, out ulong value).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_sys_reg(_vcpu, HvSysReg.SP_EL0, out ulong value).ThrowOnError();
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, hv_reg_t.HV_REG_X0 + (uint)index, out ulong value).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_reg(_vcpu, HvReg.X0 + (uint)index, out ulong value).ThrowOnError();
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -160,23 +160,23 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
if (index == 31)
|
||||
{
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, hv_sys_reg_t.HV_SYS_REG_SP_EL0, value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_sys_reg(_vcpu, HvSysReg.SP_EL0, value).ThrowOnError();
|
||||
}
|
||||
else
|
||||
{
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, hv_reg_t.HV_REG_X0 + (uint)index, value).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_reg(_vcpu, HvReg.X0 + (uint)index, value).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
public V128 GetV(int index)
|
||||
{
|
||||
HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, hv_simd_fp_reg_t.HV_SIMD_FP_REG_Q0 + (uint)index, out hv_simd_fp_uchar16_t value).ThrowOnError();
|
||||
HvApi.hv_vcpu_get_simd_fp_reg(_vcpu, HvSimdFPReg.Q0 + (uint)index, out HvSimdFPUchar16 value).ThrowOnError();
|
||||
return new V128(value.Low, value.High);
|
||||
}
|
||||
|
||||
public void SetV(int index, V128 value)
|
||||
{
|
||||
_setSimdFpReg(_vcpu, hv_simd_fp_reg_t.HV_SIMD_FP_REG_Q0 + (uint)index, value, _setSimdFpRegNativePtr).ThrowOnError();
|
||||
_setSimdFpReg(_vcpu, HvSimdFPReg.Q0 + (uint)index, value, _setSimdFpRegNativePtr).ThrowOnError();
|
||||
}
|
||||
|
||||
public void RequestInterrupt()
|
||||
@@ -193,4 +193,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
return Interlocked.Exchange(ref _interruptRequested, 0) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,4 +31,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
_block.Free(offset, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
struct HvMemoryBlockAllocation : IDisposable
|
||||
readonly struct HvMemoryBlockAllocation : IDisposable
|
||||
{
|
||||
private readonly HvMemoryBlockAllocator _owner;
|
||||
private readonly HvMemoryBlockAllocator.Block _block;
|
||||
|
@@ -1,12 +1,9 @@
|
||||
using Ryujinx.Memory;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
class HvMemoryBlockAllocator : PrivateMemoryAllocatorImpl<HvMemoryBlockAllocator.Block>
|
||||
{
|
||||
private const ulong InvalidOffset = ulong.MaxValue;
|
||||
|
||||
public class Block : PrivateMemoryAllocator.Block
|
||||
{
|
||||
private readonly HvIpaAllocator _ipaAllocator;
|
||||
@@ -21,7 +18,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
Ipa = ipaAllocator.Allocate(size);
|
||||
}
|
||||
|
||||
HvApi.hv_vm_map((ulong)Memory.Pointer, Ipa, size, hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE).ThrowOnError();
|
||||
HvApi.hv_vm_map((ulong)Memory.Pointer, Ipa, size, HvMemoryFlags.Read | HvMemoryFlags.Write).ThrowOnError();
|
||||
}
|
||||
|
||||
public override void Destroy()
|
||||
@@ -44,7 +41,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
_ipaAllocator = ipaAllocator;
|
||||
}
|
||||
|
||||
public unsafe HvMemoryBlockAllocation Allocate(ulong size, ulong alignment)
|
||||
public HvMemoryBlockAllocation Allocate(ulong size, ulong alignment)
|
||||
{
|
||||
var allocation = Allocate(size, alignment, CreateBlock);
|
||||
|
||||
|
@@ -32,7 +32,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
MappedReplicated = 0x5555555555555555,
|
||||
WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa,
|
||||
ReadWriteTrackedReplicated = ulong.MaxValue
|
||||
ReadWriteTrackedReplicated = ulong.MaxValue,
|
||||
}
|
||||
|
||||
private readonly InvalidAccessHandler _invalidAccessHandler;
|
||||
@@ -126,6 +126,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
/// <summary>
|
||||
/// Ensures the combination of virtual address and size is part of the addressable space and fully mapped.
|
||||
/// </summary>
|
||||
@@ -138,6 +139,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
throw new InvalidMemoryRegionException($"Not mapped: va=0x{va:X16}, size=0x{size:X16}");
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Map(ulong va, ulong pa, ulong size, MemoryMapFlags flags)
|
||||
@@ -306,7 +308,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
|
||||
|
||||
data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size));
|
||||
data[..size].CopyTo(_backingMemory.GetSpan(pa, size));
|
||||
|
||||
offset += size;
|
||||
}
|
||||
@@ -428,7 +430,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
|
||||
private static void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
|
||||
{
|
||||
startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1);
|
||||
endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1));
|
||||
@@ -606,7 +608,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
|
||||
|
||||
_backingMemory.GetSpan(pa, size).CopyTo(data.Slice(0, size));
|
||||
_backingMemory.GetSpan(pa, size).CopyTo(data[..size]);
|
||||
|
||||
offset += size;
|
||||
}
|
||||
@@ -723,7 +725,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
/// <param name="startVa">The virtual address of the beginning of the first page</param>
|
||||
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private int GetPagesCount(ulong va, ulong size, out ulong startVa)
|
||||
private static int GetPagesCount(ulong va, ulong size, out ulong startVa)
|
||||
{
|
||||
// WARNING: Always check if ulong does not overflow during the operations.
|
||||
startVa = va & ~(ulong)PageMask;
|
||||
@@ -814,7 +816,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
MemoryPermission.None => MemoryPermission.ReadAndWrite,
|
||||
MemoryPermission.Write => MemoryPermission.Read,
|
||||
_ => MemoryPermission.None
|
||||
_ => MemoryPermission.None,
|
||||
};
|
||||
|
||||
_addressSpace.ReprotectUser(va, size, protection);
|
||||
@@ -943,4 +945,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
private static void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,14 +3,14 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
unsafe class HvVcpu
|
||||
{
|
||||
public readonly ulong Handle;
|
||||
public readonly hv_vcpu_exit_t* ExitInfo;
|
||||
public readonly HvVcpuExit* ExitInfo;
|
||||
public readonly IHvExecutionContext ShadowContext;
|
||||
public readonly IHvExecutionContext NativeContext;
|
||||
public readonly bool IsEphemeral;
|
||||
|
||||
public HvVcpu(
|
||||
ulong handle,
|
||||
hv_vcpu_exit_t* exitInfo,
|
||||
HvVcpuExit* exitInfo,
|
||||
IHvExecutionContext shadowContext,
|
||||
IHvExecutionContext nativeContext,
|
||||
bool isEphemeral)
|
||||
@@ -22,4 +22,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
IsEphemeral = isEphemeral;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,10 +17,10 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
private const int MaxActiveVcpus = 4;
|
||||
|
||||
public static readonly HvVcpuPool Instance = new HvVcpuPool();
|
||||
public static readonly HvVcpuPool Instance = new();
|
||||
|
||||
private int _totalVcpus;
|
||||
private int _maxVcpus;
|
||||
private readonly int _maxVcpus;
|
||||
|
||||
public HvVcpuPool()
|
||||
{
|
||||
@@ -69,17 +69,17 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
bool isEphemeral = newCount > _maxVcpus - MaxActiveVcpus;
|
||||
|
||||
// Create VCPU.
|
||||
hv_vcpu_exit_t* exitInfo = null;
|
||||
HvVcpuExit* exitInfo = null;
|
||||
HvApi.hv_vcpu_create(out ulong vcpuHandle, ref exitInfo, IntPtr.Zero).ThrowOnError();
|
||||
|
||||
// Enable FP and SIMD instructions.
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, hv_sys_reg_t.HV_SYS_REG_CPACR_EL1, 0b11 << 20).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.CPACR_EL1, 0b11 << 20).ThrowOnError();
|
||||
|
||||
addressSpace.InitializeMmu(vcpuHandle);
|
||||
|
||||
HvExecutionContextVcpu nativeContext = new HvExecutionContextVcpu(vcpuHandle);
|
||||
HvExecutionContextVcpu nativeContext = new(vcpuHandle);
|
||||
|
||||
HvVcpu vcpu = new HvVcpu(vcpuHandle, exitInfo, shadowContext, nativeContext, isEphemeral);
|
||||
HvVcpu vcpu = new(vcpuHandle, exitInfo, shadowContext, nativeContext, isEphemeral);
|
||||
|
||||
return vcpu;
|
||||
}
|
||||
@@ -100,4 +100,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
Interlocked.Decrement(ref _totalVcpus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
private static int _addressSpaces;
|
||||
private static HvIpaAllocator _ipaAllocator;
|
||||
private static object _lock = new object();
|
||||
private static readonly object _lock = new();
|
||||
|
||||
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
baseAddress = ipaAllocator.Allocate(block.Size, AsIpaAlignment);
|
||||
}
|
||||
|
||||
var rwx = hv_memory_flags_t.HV_MEMORY_READ | hv_memory_flags_t.HV_MEMORY_WRITE | hv_memory_flags_t.HV_MEMORY_EXEC;
|
||||
var rwx = HvMemoryFlags.Read | HvMemoryFlags.Write | HvMemoryFlags.Exec;
|
||||
|
||||
HvApi.hv_vm_map((ulong)block.Pointer, baseAddress, block.Size, rwx).ThrowOnError();
|
||||
|
||||
@@ -65,4 +65,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -43,4 +43,4 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
void RequestInterrupt();
|
||||
bool GetAndClearInterruptRequested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,7 +23,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
PtcLoadingState.Start => LoadState.Unloaded,
|
||||
PtcLoadingState.Loading => LoadState.Loading,
|
||||
PtcLoadingState.Loaded => LoadState.Loaded,
|
||||
_ => throw new ArgumentException($"Invalid load state \"{newState}\".")
|
||||
_ => throw new ArgumentException($"Invalid load state \"{newState}\"."),
|
||||
};
|
||||
|
||||
StateChanged?.Invoke(state, current, total);
|
||||
@@ -35,4 +35,4 @@ namespace Ryujinx.Cpu.Jit
|
||||
_loadState.Continue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,4 +17,4 @@ namespace Ryujinx.Cpu.Jit
|
||||
return new JitCpuContext(_tickSource, memoryManager, for64Bit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -120,4 +120,4 @@ namespace Ryujinx.Cpu.Jit
|
||||
_impl.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,6 +19,10 @@ namespace Ryujinx.Cpu.Jit
|
||||
public void MapAsRx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadAndExecute);
|
||||
public void MapAsRwx(ulong offset, ulong size) => _impl.Reprotect(offset, size, MemoryPermission.ReadWriteExecute);
|
||||
|
||||
public void Dispose() => _impl.Dispose();
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
_impl.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -84,7 +84,6 @@ namespace Ryujinx.Cpu.Jit
|
||||
|
||||
ulong remainingSize = size;
|
||||
ulong oVa = va;
|
||||
ulong oPa = pa;
|
||||
while (remainingSize != 0)
|
||||
{
|
||||
_pageTable.Write((va / PageSize) * PteSize, PaToPte(pa));
|
||||
@@ -246,7 +245,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
|
||||
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
|
||||
|
||||
data.Slice(0, size).CopyTo(_backingMemory.GetSpan(pa, size));
|
||||
data[..size].CopyTo(_backingMemory.GetSpan(pa, size));
|
||||
|
||||
offset += size;
|
||||
}
|
||||
@@ -298,7 +297,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public unsafe WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false)
|
||||
public WritableRegion GetWritableRegion(ulong va, int size, bool tracked = false)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
@@ -345,7 +344,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
/// <param name="startVa">The virtual address of the beginning of the first page</param>
|
||||
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private int GetPagesCount(ulong va, uint size, out ulong startVa)
|
||||
private static int GetPagesCount(ulong va, uint size, out ulong startVa)
|
||||
{
|
||||
// WARNING: Always check if ulong does not overflow during the operations.
|
||||
startVa = va & ~(ulong)PageMask;
|
||||
@@ -482,7 +481,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
|
||||
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
|
||||
|
||||
_backingMemory.GetSpan(pa, size).CopyTo(data.Slice(0, size));
|
||||
_backingMemory.GetSpan(pa, size).CopyTo(data[..size]);
|
||||
|
||||
offset += size;
|
||||
}
|
||||
@@ -576,6 +575,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private ulong GetPhysicalAddress(ulong va)
|
||||
{
|
||||
// We return -1L if the virtual address is invalid or unmapped.
|
||||
@@ -586,6 +586,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
|
||||
return GetPhysicalAddressInternal(va);
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
private ulong GetPhysicalAddressInternal(ulong va)
|
||||
{
|
||||
@@ -604,7 +605,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
{
|
||||
MemoryPermission.None => 0L,
|
||||
MemoryPermission.Write => 2L << PointerTagBit,
|
||||
_ => 3L << PointerTagBit
|
||||
_ => 3L << PointerTagBit,
|
||||
};
|
||||
|
||||
int pages = GetPagesCount(va, (uint)size, out va);
|
||||
@@ -698,6 +699,8 @@ namespace Ryujinx.Cpu.Jit
|
||||
/// </summary>
|
||||
protected override void Destroy() => _pageTable.Dispose();
|
||||
|
||||
private void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private static void ThrowInvalidMemoryRegionException(string message) => throw new InvalidMemoryRegionException(message);
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
|
||||
MappedReplicated = 0x5555555555555555,
|
||||
WriteTrackedReplicated = 0xaaaaaaaaaaaaaaaa,
|
||||
ReadWriteTrackedReplicated = ulong.MaxValue
|
||||
ReadWriteTrackedReplicated = ulong.MaxValue,
|
||||
}
|
||||
|
||||
private readonly InvalidAccessHandler _invalidAccessHandler;
|
||||
@@ -404,7 +404,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
|
||||
private static void GetPageBlockRange(ulong pageStart, ulong pageEnd, out ulong startMask, out ulong endMask, out int pageIndex, out int pageEndIndex)
|
||||
{
|
||||
startMask = ulong.MaxValue << ((int)(pageStart & 31) << 1);
|
||||
endMask = ulong.MaxValue >> (64 - ((int)(pageEnd & 31) << 1));
|
||||
@@ -606,7 +606,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
/// <param name="startVa">The virtual address of the beginning of the first page</param>
|
||||
/// <remarks>This function does not differentiate between allocated and unallocated pages.</remarks>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private int GetPagesCount(ulong va, ulong size, out ulong startVa)
|
||||
private static int GetPagesCount(ulong va, ulong size, out ulong startVa)
|
||||
{
|
||||
// WARNING: Always check if ulong does not overflow during the operations.
|
||||
startVa = va & ~(ulong)PageMask;
|
||||
@@ -697,7 +697,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
{
|
||||
MemoryPermission.None => MemoryPermission.ReadAndWrite,
|
||||
MemoryPermission.Write => MemoryPermission.Read,
|
||||
_ => MemoryPermission.None
|
||||
_ => MemoryPermission.None,
|
||||
};
|
||||
|
||||
_addressSpace.Base.Reprotect(va, size, protection, false);
|
||||
|
@@ -7,6 +7,6 @@ namespace Ryujinx.Cpu
|
||||
{
|
||||
Unloaded,
|
||||
Loading,
|
||||
Loaded
|
||||
Loaded,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@ namespace Ryujinx.Cpu
|
||||
{
|
||||
private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write);
|
||||
|
||||
private readonly MemoryTracking _tracking;
|
||||
private readonly TrackingEventDelegate _trackingEvent;
|
||||
|
||||
private readonly ulong _baseAddress;
|
||||
@@ -18,12 +17,10 @@ namespace Ryujinx.Cpu
|
||||
|
||||
public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking)
|
||||
{
|
||||
_tracking = tracking;
|
||||
|
||||
_baseAddress = (ulong)addressSpace.Pointer;
|
||||
ulong endAddress = _baseAddress + addressSpace.Size;
|
||||
|
||||
_trackingEvent = new TrackingEventDelegate(tracking.VirtualMemoryEvent);
|
||||
_trackingEvent = tracking.VirtualMemoryEvent;
|
||||
bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent));
|
||||
|
||||
if (!added)
|
||||
@@ -51,6 +48,8 @@ namespace Ryujinx.Cpu
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
|
||||
NativeSignalHandler.RemoveTrackedRegion((nuint)_baseAddress);
|
||||
|
||||
if (_mirrorAddress != 0)
|
||||
|
@@ -2,7 +2,6 @@
|
||||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Memory;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
@@ -26,12 +25,12 @@ namespace Ryujinx.Cpu
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe static T Read<T>(IVirtualMemoryManager memory, ulong position) where T : unmanaged
|
||||
public static T Read<T>(IVirtualMemoryManager memory, ulong position) where T : unmanaged
|
||||
{
|
||||
return MemoryMarshal.Cast<byte, T>(memory.GetSpan(position, Unsafe.SizeOf<T>()))[0];
|
||||
}
|
||||
|
||||
public unsafe static ulong Write<T>(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged
|
||||
public static ulong Write<T>(IVirtualMemoryManager memory, ulong position, T value) where T : unmanaged
|
||||
{
|
||||
ReadOnlySpan<byte> data = MemoryMarshal.Cast<T, byte>(MemoryMarshal.CreateReadOnlySpan(ref value, 1));
|
||||
|
||||
@@ -42,22 +41,21 @@ namespace Ryujinx.Cpu
|
||||
|
||||
public static string ReadAsciiString(IVirtualMemoryManager memory, ulong position, long maxSize = -1)
|
||||
{
|
||||
using (RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream())
|
||||
using RecyclableMemoryStream ms = MemoryStreamManager.Shared.GetStream();
|
||||
|
||||
for (long offs = 0; offs < maxSize || maxSize == -1; offs++)
|
||||
{
|
||||
for (long offs = 0; offs < maxSize || maxSize == -1; offs++)
|
||||
byte value = memory.Read<byte>(position + (ulong)offs);
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
byte value = memory.Read<byte>(position + (ulong)offs);
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ms.WriteByte(value);
|
||||
break;
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString(ms.GetReadOnlySequence());
|
||||
ms.WriteByte(value);
|
||||
}
|
||||
|
||||
return Encoding.ASCII.GetString(ms.GetReadOnlySequence());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@ using System;
|
||||
|
||||
namespace Ryujinx.Cpu
|
||||
{
|
||||
struct PrivateMemoryAllocation : IDisposable
|
||||
readonly struct PrivateMemoryAllocation : IDisposable
|
||||
{
|
||||
private readonly PrivateMemoryAllocator _owner;
|
||||
private readonly PrivateMemoryAllocator.Block _block;
|
||||
@@ -27,8 +27,8 @@ namespace Ryujinx.Cpu
|
||||
|
||||
public (PrivateMemoryAllocation, PrivateMemoryAllocation) Split(ulong splitOffset)
|
||||
{
|
||||
PrivateMemoryAllocation left = new PrivateMemoryAllocation(_owner, _block, Offset, splitOffset);
|
||||
PrivateMemoryAllocation right = new PrivateMemoryAllocation(_owner, _block, Offset + splitOffset, Size - splitOffset);
|
||||
PrivateMemoryAllocation left = new(_owner, _block, Offset, splitOffset);
|
||||
PrivateMemoryAllocation right = new(_owner, _block, Offset + splitOffset, Size - splitOffset);
|
||||
|
||||
return (left, right);
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ namespace Ryujinx.Cpu
|
||||
public MemoryBlock Memory { get; private set; }
|
||||
public ulong Size { get; }
|
||||
|
||||
private struct Range : IComparable<Range>
|
||||
private readonly struct Range : IComparable<Range>
|
||||
{
|
||||
public ulong Offset { get; }
|
||||
public ulong Size { get; }
|
||||
@@ -40,7 +40,7 @@ namespace Ryujinx.Cpu
|
||||
Size = size;
|
||||
_freeRanges = new List<Range>
|
||||
{
|
||||
new Range(0, size)
|
||||
new Range(0, size),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace Ryujinx.Cpu
|
||||
{
|
||||
private const ulong InvalidOffset = ulong.MaxValue;
|
||||
|
||||
public struct Allocation
|
||||
public readonly struct Allocation
|
||||
{
|
||||
public T Block { get; }
|
||||
public ulong Offset { get; }
|
||||
@@ -265,4 +265,4 @@ namespace Ryujinx.Cpu
|
||||
_blocks.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -42,4 +42,4 @@ namespace Ryujinx.Cpu
|
||||
_tickCounter.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,16 +8,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
internal class AutoFlushCounter
|
||||
{
|
||||
// How often to flush on framebuffer change.
|
||||
private readonly static long FramebufferFlushTimer = Stopwatch.Frequency / 1000; // (1ms)
|
||||
private readonly static long _framebufferFlushTimer = Stopwatch.Frequency / 1000; // (1ms)
|
||||
|
||||
// How often to flush on draw when fast flush mode is enabled.
|
||||
private readonly static long DrawFlushTimer = Stopwatch.Frequency / 666; // (1.5ms)
|
||||
private readonly static long _drawFlushTimer = Stopwatch.Frequency / 666; // (1.5ms)
|
||||
|
||||
// Average wait time that triggers fast flush mode to be entered.
|
||||
private readonly static long FastFlushEnterThreshold = Stopwatch.Frequency / 666; // (1.5ms)
|
||||
private readonly static long _fastFlushEnterThreshold = Stopwatch.Frequency / 666; // (1.5ms)
|
||||
|
||||
// Average wait time that triggers fast flush mode to be exited.
|
||||
private readonly static long FastFlushExitThreshold = Stopwatch.Frequency / 10000; // (0.1ms)
|
||||
private readonly static long _fastFlushExitThreshold = Stopwatch.Frequency / 10000; // (0.1ms)
|
||||
|
||||
// Number of frames to average waiting times over.
|
||||
private const int SyncWaitAverageCount = 20;
|
||||
@@ -34,11 +34,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private int _consecutiveQueries;
|
||||
private int _queryCount;
|
||||
|
||||
private int[] _queryCountHistory = new int[3];
|
||||
private readonly int[] _queryCountHistory = new int[3];
|
||||
private int _queryCountHistoryIndex;
|
||||
private int _remainingQueries;
|
||||
|
||||
private long[] _syncWaitHistory = new long[SyncWaitAverageCount];
|
||||
private readonly long[] _syncWaitHistory = new long[SyncWaitAverageCount];
|
||||
private int _syncWaitHistoryIndex;
|
||||
|
||||
private bool _fastFlushMode;
|
||||
@@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return false;
|
||||
}
|
||||
|
||||
long flushTimeout = DrawFlushTimer;
|
||||
long flushTimeout = _drawFlushTimer;
|
||||
|
||||
long now = Stopwatch.GetTimestamp();
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return false;
|
||||
}
|
||||
|
||||
long flushTimeout = FramebufferFlushTimer;
|
||||
long flushTimeout = _framebufferFlushTimer;
|
||||
|
||||
long now = Stopwatch.GetTimestamp();
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
long averageWait = (long)_syncWaitHistory.Average();
|
||||
|
||||
if (_fastFlushMode ? averageWait < FastFlushExitThreshold : averageWait > FastFlushEnterThreshold)
|
||||
if (_fastFlushMode ? averageWait < _fastFlushExitThreshold : averageWait > _fastFlushEnterThreshold)
|
||||
{
|
||||
_fastFlushMode = !_fastFlushMode;
|
||||
Logger.Debug?.PrintMsg(LogClass.Gpu, $"Switched fast flush mode: ({_fastFlushMode})");
|
||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
class BackgroundResource : IDisposable
|
||||
{
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
private Device _device;
|
||||
|
||||
private CommandBufferPool _pool;
|
||||
@@ -38,10 +38,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public PersistentFlushBuffer GetFlushBuffer()
|
||||
{
|
||||
if (_flushBuffer == null)
|
||||
{
|
||||
_flushBuffer = new PersistentFlushBuffer(_gd);
|
||||
}
|
||||
_flushBuffer ??= new PersistentFlushBuffer(_gd);
|
||||
|
||||
return _flushBuffer;
|
||||
}
|
||||
@@ -55,10 +52,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
class BackgroundResources : IDisposable
|
||||
{
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
private Device _device;
|
||||
|
||||
private Dictionary<Thread, BackgroundResource> _resources;
|
||||
private readonly Dictionary<Thread, BackgroundResource> _resources;
|
||||
|
||||
public BackgroundResources(VulkanRenderer gd, Device device)
|
||||
{
|
||||
@@ -89,8 +86,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
lock (_resources)
|
||||
{
|
||||
BackgroundResource resource;
|
||||
if (!_resources.TryGetValue(thread, out resource))
|
||||
if (!_resources.TryGetValue(thread, out BackgroundResource resource))
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
|
@@ -131,7 +131,7 @@
|
||||
public void Clear(int bit)
|
||||
{
|
||||
int wordIndex = bit >> IntShift;
|
||||
int wordBit = bit & IntMask;
|
||||
int wordBit = bit & IntMask;
|
||||
|
||||
long wordMask = 1L << wordBit;
|
||||
|
||||
@@ -154,4 +154,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,6 @@
|
||||
HostMappedNoCache,
|
||||
HostMapped,
|
||||
DeviceLocal,
|
||||
DeviceLocalMapped
|
||||
DeviceLocalMapped,
|
||||
}
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private MemoryAllocation _allocation;
|
||||
private Auto<DisposableBuffer> _buffer;
|
||||
private Auto<MemoryAllocation> _allocationAuto;
|
||||
private bool _allocationImported;
|
||||
private readonly bool _allocationImported;
|
||||
private ulong _bufferHandle;
|
||||
|
||||
private CacheByRange<BufferHolder> _cachedConvertedBuffers;
|
||||
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private bool _lastAccessIsWrite;
|
||||
|
||||
private BufferAllocationType _baseType;
|
||||
private readonly BufferAllocationType _baseType;
|
||||
private BufferAllocationType _currentType;
|
||||
private bool _swapQueued;
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private int _flushTemp;
|
||||
private int _lastFlushWrite = -1;
|
||||
|
||||
private ReaderWriterLock _flushLock;
|
||||
private readonly ReaderWriterLock _flushLock;
|
||||
private FenceHolder _flushFence;
|
||||
private int _flushWaiting;
|
||||
|
||||
@@ -143,10 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cbs == null)
|
||||
{
|
||||
cbs = _gd.CommandBufferPool.Rent();
|
||||
}
|
||||
cbs ??= _gd.CommandBufferPool.Rent();
|
||||
|
||||
CommandBufferScoped cbsV = cbs.Value;
|
||||
|
||||
@@ -184,17 +181,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_swapQueued = false;
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
_swapQueued = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void ConsiderBackingSwap()
|
||||
@@ -251,13 +244,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public unsafe Auto<DisposableBufferView> CreateView(VkFormat format, int offset, int size, Action invalidateView)
|
||||
{
|
||||
var bufferViewCreateInfo = new BufferViewCreateInfo()
|
||||
var bufferViewCreateInfo = new BufferViewCreateInfo
|
||||
{
|
||||
SType = StructureType.BufferViewCreateInfo,
|
||||
Buffer = new VkBuffer(_bufferHandle),
|
||||
Format = format,
|
||||
Offset = (uint)offset,
|
||||
Range = (uint)size
|
||||
Range = (uint)size,
|
||||
};
|
||||
|
||||
_gd.Api.CreateBufferView(_device, bufferViewCreateInfo, null, out var bufferView).ThrowOnError();
|
||||
@@ -288,11 +281,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (needsBarrier)
|
||||
{
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = DefaultAccessFlags,
|
||||
DstAccessMask = DefaultAccessFlags
|
||||
DstAccessMask = DefaultAccessFlags,
|
||||
};
|
||||
|
||||
_gd.Api.CmdPipelineBarrier(
|
||||
@@ -366,14 +359,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return Unsafe.As<ulong, BufferHandle>(ref handle);
|
||||
}
|
||||
|
||||
public unsafe IntPtr Map(int offset, int mappingSize)
|
||||
public IntPtr Map(int offset, int mappingSize)
|
||||
{
|
||||
return _map;
|
||||
}
|
||||
|
||||
private void ClearFlushFence()
|
||||
{
|
||||
// Asusmes _flushLock is held as writer.
|
||||
// Assumes _flushLock is held as writer.
|
||||
|
||||
if (_flushFence != null)
|
||||
{
|
||||
@@ -421,7 +414,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe PinnedSpan<byte> GetData(int offset, int size)
|
||||
public PinnedSpan<byte> GetData(int offset, int size)
|
||||
{
|
||||
_flushLock.AcquireReaderLock(Timeout.Infinite);
|
||||
|
||||
@@ -447,26 +440,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(result, _buffer.DecrementReferenceCount);
|
||||
}
|
||||
|
||||
BackgroundResource resource = _gd.BackgroundResources.Get();
|
||||
|
||||
if (_gd.CommandBufferPool.OwnedByCurrentThread)
|
||||
{
|
||||
_gd.FlushAllCommands();
|
||||
|
||||
result = resource.GetFlushBuffer().GetBufferData(_gd.CommandBufferPool, this, offset, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
BackgroundResource resource = _gd.BackgroundResources.Get();
|
||||
|
||||
if (_gd.CommandBufferPool.OwnedByCurrentThread)
|
||||
{
|
||||
_gd.FlushAllCommands();
|
||||
|
||||
result = resource.GetFlushBuffer().GetBufferData(_gd.CommandBufferPool, this, offset, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
|
||||
}
|
||||
|
||||
_flushLock.ReleaseReaderLock();
|
||||
|
||||
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(result);
|
||||
result = resource.GetFlushBuffer().GetBufferData(resource.GetPool(), this, offset, size);
|
||||
}
|
||||
|
||||
_flushLock.ReleaseReaderLock();
|
||||
|
||||
// Flush buffer is pinned until the next GetBufferData on the thread, which is fine for current uses.
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(result);
|
||||
}
|
||||
|
||||
public unsafe Span<byte> GetDataStorage(int offset, int size)
|
||||
@@ -503,7 +494,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
WaitForFences(offset, dataSize);
|
||||
|
||||
data.Slice(0, dataSize).CopyTo(new Span<byte>((void*)(_map + offset), dataSize));
|
||||
data[..dataSize].CopyTo(new Span<byte>((void*)(_map + offset), dataSize));
|
||||
|
||||
SignalWrite(offset, dataSize);
|
||||
|
||||
@@ -542,7 +533,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (_map != IntPtr.Zero)
|
||||
{
|
||||
data.Slice(0, dataSize).CopyTo(new Span<byte>((void*)(_map + offset), dataSize));
|
||||
data[..dataSize].CopyTo(new Span<byte>((void*)(_map + offset), dataSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -657,7 +648,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int offset,
|
||||
int size)
|
||||
{
|
||||
BufferMemoryBarrier memoryBarrier = new BufferMemoryBarrier()
|
||||
BufferMemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.BufferMemoryBarrier,
|
||||
SrcAccessMask = srcAccessMask,
|
||||
@@ -666,7 +657,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
Buffer = buffer,
|
||||
Offset = (ulong)offset,
|
||||
Size = (ulong)size
|
||||
Size = (ulong)size,
|
||||
};
|
||||
|
||||
gd.Api.CmdPipelineBarrier(
|
||||
|
@@ -73,12 +73,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||
}
|
||||
|
||||
var bufferCreateInfo = new BufferCreateInfo()
|
||||
var bufferCreateInfo = new BufferCreateInfo
|
||||
{
|
||||
SType = StructureType.BufferCreateInfo,
|
||||
Size = (ulong)size,
|
||||
Usage = usage,
|
||||
SharingMode = SharingMode.Exclusive
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
};
|
||||
|
||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
||||
@@ -134,12 +134,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||
}
|
||||
|
||||
var bufferCreateInfo = new BufferCreateInfo()
|
||||
var bufferCreateInfo = new BufferCreateInfo
|
||||
{
|
||||
SType = StructureType.BufferCreateInfo,
|
||||
Size = (ulong)Environment.SystemPageSize,
|
||||
Usage = usage,
|
||||
SharingMode = SharingMode.Exclusive
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
};
|
||||
|
||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
||||
@@ -169,12 +169,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
usage |= BufferUsageFlags.IndirectBufferBit;
|
||||
}
|
||||
|
||||
var bufferCreateInfo = new BufferCreateInfo()
|
||||
var bufferCreateInfo = new BufferCreateInfo
|
||||
{
|
||||
SType = StructureType.BufferCreateInfo,
|
||||
Size = (ulong)size,
|
||||
Usage = usage,
|
||||
SharingMode = SharingMode.Exclusive
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
};
|
||||
|
||||
gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
|
||||
@@ -190,7 +190,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
BufferAllocationType.HostMapped => DefaultBufferMemoryFlags,
|
||||
BufferAllocationType.DeviceLocal => DeviceLocalBufferMemoryFlags,
|
||||
BufferAllocationType.DeviceLocalMapped => DeviceLocalMappedBufferMemoryFlags,
|
||||
_ => DefaultBufferMemoryFlags
|
||||
_ => DefaultBufferMemoryFlags,
|
||||
};
|
||||
|
||||
// If an allocation with this memory type fails, fall back to the previous one.
|
||||
@@ -216,7 +216,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return (buffer, allocation, type);
|
||||
}
|
||||
|
||||
public unsafe BufferHolder Create(
|
||||
public BufferHolder Create(
|
||||
VulkanRenderer gd,
|
||||
int size,
|
||||
bool forConditionalRendering = false,
|
||||
|
@@ -4,7 +4,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
struct BufferState : IDisposable
|
||||
{
|
||||
public static BufferState Null => new BufferState(null, 0, 0);
|
||||
public static BufferState Null => new(null, 0, 0);
|
||||
|
||||
private readonly int _offset;
|
||||
private readonly int _size;
|
||||
@@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
buffer?.IncrementReferenceCount();
|
||||
}
|
||||
|
||||
public void BindTransformFeedbackBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding)
|
||||
public readonly void BindTransformFeedbackBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding)
|
||||
{
|
||||
if (_buffer != null)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
_buffer?.DecrementReferenceCount();
|
||||
}
|
||||
|
@@ -2,13 +2,13 @@
|
||||
{
|
||||
internal class BufferUsageBitmap
|
||||
{
|
||||
private BitMap _bitmap;
|
||||
private int _size;
|
||||
private int _granularity;
|
||||
private int _bits;
|
||||
private readonly BitMap _bitmap;
|
||||
private readonly int _size;
|
||||
private readonly int _granularity;
|
||||
private readonly int _bits;
|
||||
|
||||
private int _intsPerCb;
|
||||
private int _bitsPerCb;
|
||||
private readonly int _intsPerCb;
|
||||
private readonly int _bitsPerCb;
|
||||
|
||||
public BufferUsageBitmap(int size, int granularity)
|
||||
{
|
||||
|
@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = null;
|
||||
}
|
||||
|
||||
public bool KeyEqual(ICacheKey other)
|
||||
public readonly bool KeyEqual(ICacheKey other)
|
||||
{
|
||||
return other is I8ToI16CacheKey;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
_gd.PipelineInternal.DirtyIndexBuffer(_buffer);
|
||||
}
|
||||
@@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = null;
|
||||
}
|
||||
|
||||
public bool KeyEqual(ICacheKey other)
|
||||
public readonly bool KeyEqual(ICacheKey other)
|
||||
{
|
||||
return other is AlignedVertexBufferCacheKey entry &&
|
||||
entry._stride == _stride &&
|
||||
@@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
_gd.PipelineInternal.DirtyVertexBuffer(_buffer);
|
||||
}
|
||||
@@ -73,8 +73,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
struct TopologyConversionCacheKey : ICacheKey
|
||||
{
|
||||
private IndexBufferPattern _pattern;
|
||||
private int _indexSize;
|
||||
private readonly IndexBufferPattern _pattern;
|
||||
private readonly int _indexSize;
|
||||
|
||||
// Used to notify the pipeline that bindings have invalidated on dispose.
|
||||
private readonly VulkanRenderer _gd;
|
||||
@@ -88,7 +88,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = null;
|
||||
}
|
||||
|
||||
public bool KeyEqual(ICacheKey other)
|
||||
public readonly bool KeyEqual(ICacheKey other)
|
||||
{
|
||||
return other is TopologyConversionCacheKey entry &&
|
||||
entry._pattern == _pattern &&
|
||||
@@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
_gd.PipelineInternal.DirtyIndexBuffer(_buffer);
|
||||
}
|
||||
@@ -147,9 +147,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
struct IndirectDataCacheKey : ICacheKey
|
||||
readonly struct IndirectDataCacheKey : ICacheKey
|
||||
{
|
||||
private IndexBufferPattern _pattern;
|
||||
private readonly IndexBufferPattern _pattern;
|
||||
|
||||
public IndirectDataCacheKey(IndexBufferPattern pattern)
|
||||
{
|
||||
@@ -168,12 +168,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
struct DrawCountCacheKey : ICacheKey
|
||||
{
|
||||
public bool KeyEqual(ICacheKey other)
|
||||
public readonly bool KeyEqual(ICacheKey other)
|
||||
{
|
||||
return other is DrawCountCacheKey;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -214,7 +214,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DependencyList = null;
|
||||
}
|
||||
|
||||
public void InvalidateDependencies()
|
||||
public readonly void InvalidateDependencies()
|
||||
{
|
||||
if (DependencyList != null)
|
||||
{
|
||||
@@ -317,7 +317,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearRange(int offset, int size)
|
||||
public readonly void ClearRange(int offset, int size)
|
||||
{
|
||||
if (_ranges != null && _ranges.Count > 0)
|
||||
{
|
||||
@@ -356,15 +356,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private List<Entry> GetEntries(int offset, int size)
|
||||
{
|
||||
if (_ranges == null)
|
||||
{
|
||||
_ranges = new Dictionary<ulong, List<Entry>>();
|
||||
}
|
||||
_ranges ??= new Dictionary<ulong, List<Entry>>();
|
||||
|
||||
ulong key = PackRange(offset, size);
|
||||
|
||||
List<Entry> value;
|
||||
if (!_ranges.TryGetValue(key, out value))
|
||||
if (!_ranges.TryGetValue(key, out List<Entry> value))
|
||||
{
|
||||
value = new List<Entry>();
|
||||
_ranges.Add(key, value);
|
||||
|
@@ -2,7 +2,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Thread = System.Threading.Thread;
|
||||
using System.Threading;
|
||||
using Semaphore = Silk.NET.Vulkan.Semaphore;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@@ -10,8 +11,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
public const int MaxCommandBuffers = 16;
|
||||
|
||||
private int _totalCommandBuffers;
|
||||
private int _totalCommandBuffersMask;
|
||||
private readonly int _totalCommandBuffers;
|
||||
private readonly int _totalCommandBuffersMask;
|
||||
|
||||
private readonly Vk _api;
|
||||
private readonly Device _device;
|
||||
@@ -36,12 +37,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void Initialize(Vk api, Device device, CommandPool pool)
|
||||
{
|
||||
var allocateInfo = new CommandBufferAllocateInfo()
|
||||
var allocateInfo = new CommandBufferAllocateInfo
|
||||
{
|
||||
SType = StructureType.CommandBufferAllocateInfo,
|
||||
CommandBufferCount = 1,
|
||||
CommandPool = pool,
|
||||
Level = CommandBufferLevel.Primary
|
||||
Level = CommandBufferLevel.Primary,
|
||||
};
|
||||
|
||||
api.AllocateCommandBuffers(device, allocateInfo, out CommandBuffer);
|
||||
@@ -67,12 +68,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_queueLock = queueLock;
|
||||
_owner = Thread.CurrentThread;
|
||||
|
||||
var commandPoolCreateInfo = new CommandPoolCreateInfo()
|
||||
var commandPoolCreateInfo = new CommandPoolCreateInfo
|
||||
{
|
||||
SType = StructureType.CommandPoolCreateInfo,
|
||||
QueueFamilyIndex = queueFamilyIndex,
|
||||
Flags = CommandPoolCreateFlags.TransientBit |
|
||||
CommandPoolCreateFlags.ResetCommandBufferBit
|
||||
CommandPoolCreateFlags.ResetCommandBufferBit,
|
||||
};
|
||||
|
||||
api.CreateCommandPool(device, commandPoolCreateInfo, null, out _pool).ThrowOnError();
|
||||
@@ -243,9 +244,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_inUseCount++;
|
||||
|
||||
var commandBufferBeginInfo = new CommandBufferBeginInfo()
|
||||
var commandBufferBeginInfo = new CommandBufferBeginInfo
|
||||
{
|
||||
SType = StructureType.CommandBufferBeginInfo
|
||||
SType = StructureType.CommandBufferBeginInfo,
|
||||
};
|
||||
|
||||
_api.BeginCommandBuffer(entry.CommandBuffer, commandBufferBeginInfo).ThrowOnError();
|
||||
@@ -291,7 +292,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
fixed (PipelineStageFlags* pWaitDstStageMask = waitDstStageMask)
|
||||
{
|
||||
SubmitInfo sInfo = new SubmitInfo()
|
||||
SubmitInfo sInfo = new()
|
||||
{
|
||||
SType = StructureType.SubmitInfo,
|
||||
WaitSemaphoreCount = waitSemaphores != null ? (uint)waitSemaphores.Length : 0,
|
||||
@@ -300,7 +301,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
CommandBufferCount = 1,
|
||||
PCommandBuffers = &commandBuffer,
|
||||
SignalSemaphoreCount = signalSemaphores != null ? (uint)signalSemaphores.Length : 0,
|
||||
PSignalSemaphores = pSignalSemaphores
|
||||
PSignalSemaphores = pSignalSemaphores,
|
||||
};
|
||||
|
||||
lock (_queueLock)
|
||||
|
@@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
private DescriptorSetManager.DescriptorPoolHolder _holder;
|
||||
private readonly DescriptorSet[] _descriptorSets;
|
||||
public int SetsCount => _descriptorSets.Length;
|
||||
public readonly int SetsCount => _descriptorSets.Length;
|
||||
|
||||
public DescriptorSetCollection(DescriptorSetManager.DescriptorPoolHolder holder, DescriptorSet[] descriptorSets)
|
||||
{
|
||||
@@ -20,10 +20,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Span<DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[count];
|
||||
|
||||
infos.Fill(new DescriptorBufferInfo()
|
||||
infos.Fill(new DescriptorBufferInfo
|
||||
{
|
||||
Buffer = dummyBuffer,
|
||||
Range = Vk.WholeSize
|
||||
Range = Vk.WholeSize,
|
||||
});
|
||||
|
||||
UpdateBuffers(setIndex, baseBinding, infos, type);
|
||||
@@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)bindingIndex,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = 1,
|
||||
PBufferInfo = &bufferInfo
|
||||
PBufferInfo = &bufferInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@@ -63,7 +63,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)baseBinding,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = (uint)bufferInfo.Length,
|
||||
PBufferInfo = pBufferInfo
|
||||
PBufferInfo = pBufferInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)bindingIndex,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = 1,
|
||||
PImageInfo = &imageInfo
|
||||
PImageInfo = &imageInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)baseBinding,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = (uint)imageInfo.Length,
|
||||
PImageInfo = pImageInfo
|
||||
PImageInfo = pImageInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@@ -141,7 +141,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)(baseBinding + i),
|
||||
DescriptorType = DescriptorType.CombinedImageSampler,
|
||||
DescriptorCount = (uint)count,
|
||||
PImageInfo = pImageInfo
|
||||
PImageInfo = pImageInfo,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@@ -163,7 +163,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)bindingIndex,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = 1,
|
||||
PTexelBufferView = &texelBufferView
|
||||
PTexelBufferView = &texelBufferView,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)baseBinding + i,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = count,
|
||||
PTexelBufferView = pTexelBufferView + i
|
||||
PTexelBufferView = pTexelBufferView + i,
|
||||
};
|
||||
|
||||
_holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
|
||||
@@ -208,7 +208,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public DescriptorSet[] GetSets()
|
||||
public readonly DescriptorSet[] GetSets()
|
||||
{
|
||||
return _descriptorSets;
|
||||
}
|
||||
|
@@ -24,14 +24,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Api = api;
|
||||
Device = device;
|
||||
|
||||
var poolSizes = new DescriptorPoolSize[]
|
||||
var poolSizes = new[]
|
||||
{
|
||||
new DescriptorPoolSize(DescriptorType.UniformBuffer, (1 + Constants.MaxUniformBufferBindings) * DescriptorPoolMultiplier),
|
||||
new DescriptorPoolSize(DescriptorType.StorageBuffer, Constants.MaxStorageBufferBindings * DescriptorPoolMultiplier),
|
||||
new DescriptorPoolSize(DescriptorType.CombinedImageSampler, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
|
||||
new DescriptorPoolSize(DescriptorType.StorageImage, Constants.MaxImageBindings * DescriptorPoolMultiplier),
|
||||
new DescriptorPoolSize(DescriptorType.UniformTexelBuffer, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
|
||||
new DescriptorPoolSize(DescriptorType.StorageTexelBuffer, Constants.MaxImageBindings * DescriptorPoolMultiplier)
|
||||
new DescriptorPoolSize(DescriptorType.StorageTexelBuffer, Constants.MaxImageBindings * DescriptorPoolMultiplier),
|
||||
};
|
||||
|
||||
uint maxSets = (uint)poolSizes.Length * DescriptorPoolMultiplier;
|
||||
@@ -40,19 +40,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (DescriptorPoolSize* pPoolsSize = poolSizes)
|
||||
{
|
||||
var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo()
|
||||
var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo
|
||||
{
|
||||
SType = StructureType.DescriptorPoolCreateInfo,
|
||||
MaxSets = maxSets,
|
||||
PoolSizeCount = (uint)poolSizes.Length,
|
||||
PPoolSizes = pPoolsSize
|
||||
PPoolSizes = pPoolsSize,
|
||||
};
|
||||
|
||||
Api.CreateDescriptorPool(device, descriptorPoolCreateInfo, null, out _pool).ThrowOnError();
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe DescriptorSetCollection AllocateDescriptorSets(ReadOnlySpan<DescriptorSetLayout> layouts)
|
||||
public DescriptorSetCollection AllocateDescriptorSets(ReadOnlySpan<DescriptorSetLayout> layouts)
|
||||
{
|
||||
TryAllocateDescriptorSets(layouts, isTry: false, out var dsc);
|
||||
return dsc;
|
||||
@@ -73,12 +73,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
fixed (DescriptorSetLayout* pLayouts = layouts)
|
||||
{
|
||||
var descriptorSetAllocateInfo = new DescriptorSetAllocateInfo()
|
||||
var descriptorSetAllocateInfo = new DescriptorSetAllocateInfo
|
||||
{
|
||||
SType = StructureType.DescriptorSetAllocateInfo,
|
||||
DescriptorPool = _pool,
|
||||
DescriptorSetCount = (uint)layouts.Length,
|
||||
PSetLayouts = pLayouts
|
||||
PSetLayouts = pLayouts,
|
||||
};
|
||||
|
||||
var result = Api.AllocateDescriptorSets(Device, &descriptorSetAllocateInfo, pDescriptorSets);
|
||||
@@ -142,6 +142,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
@@ -186,15 +187,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
_currentPool?.Dispose();
|
||||
}
|
||||
_currentPool?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
Dispose(true);
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,11 @@
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@@ -14,25 +17,25 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private ShaderCollection _program;
|
||||
|
||||
private Auto<DisposableBuffer>[] _uniformBufferRefs;
|
||||
private Auto<DisposableBuffer>[] _storageBufferRefs;
|
||||
private Auto<DisposableImageView>[] _textureRefs;
|
||||
private Auto<DisposableSampler>[] _samplerRefs;
|
||||
private Auto<DisposableImageView>[] _imageRefs;
|
||||
private TextureBuffer[] _bufferTextureRefs;
|
||||
private TextureBuffer[] _bufferImageRefs;
|
||||
private GAL.Format[] _bufferImageFormats;
|
||||
private readonly Auto<DisposableBuffer>[] _uniformBufferRefs;
|
||||
private readonly Auto<DisposableBuffer>[] _storageBufferRefs;
|
||||
private readonly Auto<DisposableImageView>[] _textureRefs;
|
||||
private readonly Auto<DisposableSampler>[] _samplerRefs;
|
||||
private readonly Auto<DisposableImageView>[] _imageRefs;
|
||||
private readonly TextureBuffer[] _bufferTextureRefs;
|
||||
private readonly TextureBuffer[] _bufferImageRefs;
|
||||
private readonly Format[] _bufferImageFormats;
|
||||
|
||||
private DescriptorBufferInfo[] _uniformBuffers;
|
||||
private DescriptorBufferInfo[] _storageBuffers;
|
||||
private DescriptorImageInfo[] _textures;
|
||||
private DescriptorImageInfo[] _images;
|
||||
private BufferView[] _bufferTextures;
|
||||
private BufferView[] _bufferImages;
|
||||
private readonly DescriptorBufferInfo[] _uniformBuffers;
|
||||
private readonly DescriptorBufferInfo[] _storageBuffers;
|
||||
private readonly DescriptorImageInfo[] _textures;
|
||||
private readonly DescriptorImageInfo[] _images;
|
||||
private readonly BufferView[] _bufferTextures;
|
||||
private readonly BufferView[] _bufferImages;
|
||||
|
||||
private bool[] _uniformSet;
|
||||
private bool[] _storageSet;
|
||||
private Silk.NET.Vulkan.Buffer _cachedSupportBuffer;
|
||||
private readonly bool[] _uniformSet;
|
||||
private readonly bool[] _storageSet;
|
||||
private Buffer _cachedSupportBuffer;
|
||||
|
||||
[Flags]
|
||||
private enum DirtyFlags
|
||||
@@ -42,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Storage = 1 << 1,
|
||||
Texture = 1 << 2,
|
||||
Image = 1 << 3,
|
||||
All = Uniform | Storage | Texture | Image
|
||||
All = Uniform | Storage | Texture | Image,
|
||||
}
|
||||
|
||||
private DirtyFlags _dirty;
|
||||
@@ -66,7 +69,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_imageRefs = new Auto<DisposableImageView>[Constants.MaxImageBindings * 2];
|
||||
_bufferTextureRefs = new TextureBuffer[Constants.MaxTextureBindings * 2];
|
||||
_bufferImageRefs = new TextureBuffer[Constants.MaxImageBindings * 2];
|
||||
_bufferImageFormats = new GAL.Format[Constants.MaxImageBindings * 2];
|
||||
_bufferImageFormats = new Format[Constants.MaxImageBindings * 2];
|
||||
|
||||
_uniformBuffers = new DescriptorBufferInfo[Constants.MaxUniformBufferBindings];
|
||||
_storageBuffers = new DescriptorBufferInfo[Constants.MaxStorageBufferBindings];
|
||||
@@ -75,9 +78,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_bufferTextures = new BufferView[Constants.MaxTexturesPerStage];
|
||||
_bufferImages = new BufferView[Constants.MaxImagesPerStage];
|
||||
|
||||
var initialImageInfo = new DescriptorImageInfo()
|
||||
var initialImageInfo = new DescriptorImageInfo
|
||||
{
|
||||
ImageLayout = ImageLayout.General
|
||||
ImageLayout = ImageLayout.General,
|
||||
};
|
||||
|
||||
_textures.AsSpan().Fill(initialImageInfo);
|
||||
@@ -106,7 +109,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
1,
|
||||
1,
|
||||
4,
|
||||
GAL.Format.R8G8B8A8Unorm,
|
||||
Format.R8G8B8A8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
@@ -114,7 +117,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SwizzleComponent.Blue,
|
||||
SwizzleComponent.Alpha), 1f);
|
||||
|
||||
_dummySampler = (SamplerHolder)gd.CreateSampler(new GAL.SamplerCreateInfo(
|
||||
_dummySampler = (SamplerHolder)gd.CreateSampler(new SamplerCreateInfo(
|
||||
MinFilter.Nearest,
|
||||
MagFilter.Nearest,
|
||||
false,
|
||||
@@ -122,7 +125,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
AddressMode.Repeat,
|
||||
AddressMode.Repeat,
|
||||
CompareMode.None,
|
||||
GAL.CompareOp.Always,
|
||||
CompareOp.Always,
|
||||
new ColorF(0, 0, 0, 0),
|
||||
0,
|
||||
0,
|
||||
@@ -142,7 +145,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_dirty = DirtyFlags.All;
|
||||
}
|
||||
|
||||
public void SetImage(int binding, ITexture image, GAL.Format imageFormat)
|
||||
public void SetImage(int binding, ITexture image, Format imageFormat)
|
||||
{
|
||||
if (image is TextureBuffer imageBuffer)
|
||||
{
|
||||
@@ -181,10 +184,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false, isSSBO: true);
|
||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
||||
|
||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
||||
DescriptorBufferInfo info = new()
|
||||
{
|
||||
Offset = (ulong)buffer.Offset,
|
||||
Range = (ulong)buffer.Size
|
||||
Range = (ulong)buffer.Size,
|
||||
};
|
||||
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
||||
|
||||
@@ -209,10 +212,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
|
||||
|
||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
||||
DescriptorBufferInfo info = new()
|
||||
{
|
||||
Offset = 0,
|
||||
Range = Vk.WholeSize
|
||||
Range = Vk.WholeSize,
|
||||
};
|
||||
ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
|
||||
|
||||
@@ -289,10 +292,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
|
||||
ref Auto<DisposableBuffer> currentVkBuffer = ref _uniformBufferRefs[index];
|
||||
|
||||
DescriptorBufferInfo info = new DescriptorBufferInfo()
|
||||
DescriptorBufferInfo info = new()
|
||||
{
|
||||
Offset = (ulong)buffer.Offset,
|
||||
Range = (ulong)buffer.Size
|
||||
Range = (ulong)buffer.Size,
|
||||
};
|
||||
ref DescriptorBufferInfo currentInfo = ref _uniformBuffers[index];
|
||||
|
||||
@@ -400,11 +403,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_uniformSet[0] = true;
|
||||
}
|
||||
|
||||
uniformBuffer[0] = new DescriptorBufferInfo()
|
||||
uniformBuffer[0] = new DescriptorBufferInfo
|
||||
{
|
||||
Offset = 0,
|
||||
Range = (ulong)SupportBuffer.RequiredSize,
|
||||
Buffer = _cachedSupportBuffer
|
||||
Buffer = _cachedSupportBuffer,
|
||||
};
|
||||
|
||||
dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
|
||||
@@ -474,7 +477,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
dsc.UpdateImages(0, binding, textures.Slice(0, count), DescriptorType.CombinedImageSampler);
|
||||
dsc.UpdateImages(0, binding, textures[..count], DescriptorType.CombinedImageSampler);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -485,7 +488,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
bufferTextures[i] = _bufferTextureRefs[binding + i]?.GetBufferView(cbs) ?? default;
|
||||
}
|
||||
|
||||
dsc.UpdateBufferImages(0, binding, bufferTextures.Slice(0, count), DescriptorType.UniformTexelBuffer);
|
||||
dsc.UpdateBufferImages(0, binding, bufferTextures[..count], DescriptorType.UniformTexelBuffer);
|
||||
}
|
||||
}
|
||||
else if (setIndex == PipelineBase.ImageSetIndex)
|
||||
@@ -499,7 +502,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
images[i].ImageView = _imageRefs[binding + i]?.Get(cbs).Value ?? default;
|
||||
}
|
||||
|
||||
dsc.UpdateImages(0, binding, images.Slice(0, count), DescriptorType.StorageImage);
|
||||
dsc.UpdateImages(0, binding, images[..count], DescriptorType.StorageImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -510,7 +513,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
bufferImages[i] = _bufferImageRefs[binding + i]?.GetBufferView(cbs, _bufferImageFormats[binding + i]) ?? default;
|
||||
}
|
||||
|
||||
dsc.UpdateBufferImages(0, binding, bufferImages.Slice(0, count), DescriptorType.StorageTexelBuffer);
|
||||
dsc.UpdateBufferImages(0, binding, bufferImages[..count], DescriptorType.StorageTexelBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -540,7 +543,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DstBinding = (uint)baseBinding,
|
||||
DescriptorType = type,
|
||||
DescriptorCount = (uint)bufferInfo.Length,
|
||||
PBufferInfo = pBufferInfo
|
||||
PBufferInfo = pBufferInfo,
|
||||
};
|
||||
|
||||
_gd.PushDescriptorApi.CmdPushDescriptorSet(cbs.CommandBuffer, pbp, _program.PipelineLayout, 0, 1, &writeDescriptorSet);
|
||||
@@ -554,11 +557,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Span<DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];
|
||||
|
||||
uniformBuffer[0] = new DescriptorBufferInfo()
|
||||
uniformBuffer[0] = new DescriptorBufferInfo
|
||||
{
|
||||
Offset = 0,
|
||||
Range = (ulong)SupportBuffer.RequiredSize,
|
||||
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value
|
||||
Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value,
|
||||
};
|
||||
|
||||
_uniformSet[0] = true;
|
||||
@@ -620,7 +623,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Array.Clear(_storageSet);
|
||||
}
|
||||
|
||||
private void SwapBuffer(Auto<DisposableBuffer>[] list, Auto<DisposableBuffer> from, Auto<DisposableBuffer> to)
|
||||
private static void SwapBuffer(Auto<DisposableBuffer>[] list, Auto<DisposableBuffer> from, Auto<DisposableBuffer> to)
|
||||
{
|
||||
for (int i = 0; i < list.Length; i++)
|
||||
{
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Buffer = Silk.NET.Vulkan.Buffer;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@@ -8,9 +9,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Vk _api;
|
||||
private readonly Device _device;
|
||||
|
||||
public Silk.NET.Vulkan.Buffer Value { get; }
|
||||
public Buffer Value { get; }
|
||||
|
||||
public DisposableBuffer(Vk api, Device device, Silk.NET.Vulkan.Buffer buffer)
|
||||
public DisposableBuffer(Vk api, Device device, Buffer buffer)
|
||||
{
|
||||
_api = api;
|
||||
_device = device;
|
||||
|
@@ -5,10 +5,12 @@ using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Extent2D = Ryujinx.Graphics.GAL.Extents2D;
|
||||
using Format = Silk.NET.Vulkan.Format;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal partial class FsrScalingFilter : IScalingFilter
|
||||
internal class FsrScalingFilter : IScalingFilter
|
||||
{
|
||||
private readonly VulkanRenderer _renderer;
|
||||
private PipelineHelperShader _pipeline;
|
||||
@@ -66,16 +68,16 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
||||
|
||||
_sampler = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
_sampler = _renderer.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
|
||||
_scalingProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(scalingShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(scalingShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, scalingResourceLayout);
|
||||
|
||||
_sharpeningProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(sharpeningShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(sharpeningShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, sharpeningResourceLayout);
|
||||
}
|
||||
|
||||
@@ -83,7 +85,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
TextureView view,
|
||||
CommandBufferScoped cbs,
|
||||
Auto<DisposableImageView> destinationTexture,
|
||||
Silk.NET.Vulkan.Format format,
|
||||
Format format,
|
||||
int width,
|
||||
int height,
|
||||
Extent2D source,
|
||||
@@ -136,14 +138,14 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
destination.Y1,
|
||||
destination.Y2,
|
||||
scaleX,
|
||||
scaleY
|
||||
scaleY,
|
||||
};
|
||||
|
||||
int rangeSize = dimensionsBuffer.Length * sizeof(float);
|
||||
var bufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, rangeSize);
|
||||
_renderer.BufferManager.SetData(bufferHandle, 0, dimensionsBuffer);
|
||||
|
||||
ReadOnlySpan<float> sharpeningBuffer = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f)};
|
||||
ReadOnlySpan<float> sharpeningBuffer = stackalloc float[] { 1.5f - (Level * 0.01f * 1.5f) };
|
||||
var sharpeningBufferHandle = _renderer.BufferManager.CreateWithHandle(_renderer, sizeof(float));
|
||||
_renderer.BufferManager.SetData(sharpeningBufferHandle, 0, sharpeningBuffer);
|
||||
|
||||
@@ -172,4 +174,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
_renderer.BufferManager.Delete(sharpeningBufferHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,16 +4,17 @@ using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal partial class FxaaPostProcessingEffect : IPostProcessingEffect
|
||||
internal class FxaaPostProcessingEffect : IPostProcessingEffect
|
||||
{
|
||||
private readonly VulkanRenderer _renderer;
|
||||
private ISampler _samplerLinear;
|
||||
private ShaderCollection _shaderProgram;
|
||||
|
||||
private PipelineHelperShader _pipeline;
|
||||
private readonly PipelineHelperShader _pipeline;
|
||||
private TextureView _texture;
|
||||
|
||||
public FxaaPostProcessingEffect(VulkanRenderer renderer, Device device)
|
||||
@@ -43,11 +44,11 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 1)
|
||||
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
||||
|
||||
_samplerLinear = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
_samplerLinear = _renderer.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
|
||||
_shaderProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(shader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(shader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, resourceLayout);
|
||||
}
|
||||
|
||||
@@ -86,4 +87,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
return _texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -7,4 +7,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
const int LocalGroupSize = 64;
|
||||
TextureView Run(TextureView view, CommandBufferScoped cbs, int width, int height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,4 +17,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
Extent2D source,
|
||||
Extent2D destination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,4 +12,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
public float Width;
|
||||
public float Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,10 +4,12 @@ using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
{
|
||||
internal partial class SmaaPostProcessingEffect : IPostProcessingEffect
|
||||
internal class SmaaPostProcessingEffect : IPostProcessingEffect
|
||||
{
|
||||
public const int AreaWidth = 160;
|
||||
public const int AreaHeight = 560;
|
||||
@@ -63,7 +65,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
_searchTexture?.Dispose();
|
||||
}
|
||||
|
||||
private unsafe void RecreateShaders(int width, int height)
|
||||
private void RecreateShaders(int width, int height)
|
||||
{
|
||||
_recreatePipelines = false;
|
||||
|
||||
@@ -94,9 +96,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
.Add(ResourceStages.Compute, ResourceType.TextureAndSampler, 3)
|
||||
.Add(ResourceStages.Compute, ResourceType.Image, 0).Build();
|
||||
|
||||
_samplerLinear = _renderer.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
_samplerLinear = _renderer.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
|
||||
_specConstants = new SmaaConstants()
|
||||
_specConstants = new SmaaConstants
|
||||
{
|
||||
Width = width,
|
||||
Height = height,
|
||||
@@ -116,17 +118,17 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
|
||||
_edgeProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(edgeShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(edgeShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, edgeResourceLayout, new[] { specInfo });
|
||||
|
||||
_blendProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(blendShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(blendShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, blendResourceLayout, new[] { specInfo });
|
||||
|
||||
_neighbourProgram = _renderer.CreateProgramWithMinimalLayout(new[]
|
||||
{
|
||||
new ShaderSource(neighbourShader, ShaderStage.Compute, TargetLanguage.Spirv)
|
||||
new ShaderSource(neighbourShader, ShaderStage.Compute, TargetLanguage.Spirv),
|
||||
}, neighbourResourceLayout, new[] { specInfo });
|
||||
}
|
||||
|
||||
@@ -148,7 +150,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
GAL.Format.R8G8Unorm,
|
||||
Format.R8G8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
@@ -164,7 +166,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
GAL.Format.R8Unorm,
|
||||
Format.R8Unorm,
|
||||
DepthStencilMode.Depth,
|
||||
Target.Texture2D,
|
||||
SwizzleComponent.Red,
|
||||
@@ -264,4 +266,4 @@ namespace Ryujinx.Graphics.Vulkan.Effects
|
||||
_pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,14 @@ using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using BlendFactor = Silk.NET.Vulkan.BlendFactor;
|
||||
using BlendOp = Silk.NET.Vulkan.BlendOp;
|
||||
using CompareOp = Silk.NET.Vulkan.CompareOp;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using FrontFace = Silk.NET.Vulkan.FrontFace;
|
||||
using IndexType = Silk.NET.Vulkan.IndexType;
|
||||
using PrimitiveTopology = Silk.NET.Vulkan.PrimitiveTopology;
|
||||
using StencilOp = Silk.NET.Vulkan.StencilOp;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@@ -18,7 +26,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ShaderStage.TessellationEvaluation => ShaderStageFlags.TessellationEvaluationBit,
|
||||
ShaderStage.Fragment => ShaderStageFlags.FragmentBit,
|
||||
ShaderStage.Compute => ShaderStageFlags.ComputeBit,
|
||||
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (ShaderStageFlags)0)
|
||||
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (ShaderStageFlags)0),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -32,7 +40,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ShaderStage.TessellationEvaluation => PipelineStageFlags.TessellationEvaluationShaderBit,
|
||||
ShaderStage.Fragment => PipelineStageFlags.FragmentShaderBit,
|
||||
ShaderStage.Compute => PipelineStageFlags.ComputeShaderBit,
|
||||
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (PipelineStageFlags)0)
|
||||
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (PipelineStageFlags)0),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -82,7 +90,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ResourceType.Image => DescriptorType.StorageImage,
|
||||
ResourceType.BufferTexture => DescriptorType.UniformTexelBuffer,
|
||||
ResourceType.BufferImage => DescriptorType.StorageTexelBuffer,
|
||||
_ => throw new ArgumentException($"Invalid resource type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid resource type \"{type}\"."),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -98,128 +106,128 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
AddressMode.ClampToBorder => SamplerAddressMode.ClampToBorder,
|
||||
AddressMode.MirroredRepeat => SamplerAddressMode.MirroredRepeat,
|
||||
AddressMode.ClampToEdge => SamplerAddressMode.ClampToEdge,
|
||||
_ => LogInvalidAndReturn(mode, nameof(AddressMode), SamplerAddressMode.ClampToEdge) // TODO: Should be clamp.
|
||||
_ => LogInvalidAndReturn(mode, nameof(AddressMode), SamplerAddressMode.ClampToEdge), // TODO: Should be clamp.
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.BlendFactor Convert(this GAL.BlendFactor factor)
|
||||
public static BlendFactor Convert(this GAL.BlendFactor factor)
|
||||
{
|
||||
return factor switch
|
||||
{
|
||||
GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => Silk.NET.Vulkan.BlendFactor.Zero,
|
||||
GAL.BlendFactor.One or GAL.BlendFactor.OneGl => Silk.NET.Vulkan.BlendFactor.One,
|
||||
GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => Silk.NET.Vulkan.BlendFactor.SrcColor,
|
||||
GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrcColor,
|
||||
GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => Silk.NET.Vulkan.BlendFactor.SrcAlpha,
|
||||
GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrcAlpha,
|
||||
GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => Silk.NET.Vulkan.BlendFactor.DstAlpha,
|
||||
GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusDstAlpha,
|
||||
GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => Silk.NET.Vulkan.BlendFactor.DstColor,
|
||||
GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusDstColor,
|
||||
GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => Silk.NET.Vulkan.BlendFactor.SrcAlphaSaturate,
|
||||
GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => Silk.NET.Vulkan.BlendFactor.Src1Color,
|
||||
GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrc1Color,
|
||||
GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => Silk.NET.Vulkan.BlendFactor.Src1Alpha,
|
||||
GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => Silk.NET.Vulkan.BlendFactor.OneMinusSrc1Alpha,
|
||||
GAL.BlendFactor.ConstantColor => Silk.NET.Vulkan.BlendFactor.ConstantColor,
|
||||
GAL.BlendFactor.OneMinusConstantColor => Silk.NET.Vulkan.BlendFactor.OneMinusConstantColor,
|
||||
GAL.BlendFactor.ConstantAlpha => Silk.NET.Vulkan.BlendFactor.ConstantAlpha,
|
||||
GAL.BlendFactor.OneMinusConstantAlpha => Silk.NET.Vulkan.BlendFactor.OneMinusConstantAlpha,
|
||||
_ => LogInvalidAndReturn(factor, nameof(GAL.BlendFactor), Silk.NET.Vulkan.BlendFactor.Zero)
|
||||
GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => BlendFactor.Zero,
|
||||
GAL.BlendFactor.One or GAL.BlendFactor.OneGl => BlendFactor.One,
|
||||
GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => BlendFactor.SrcColor,
|
||||
GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => BlendFactor.OneMinusSrcColor,
|
||||
GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => BlendFactor.SrcAlpha,
|
||||
GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => BlendFactor.OneMinusSrcAlpha,
|
||||
GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => BlendFactor.DstAlpha,
|
||||
GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => BlendFactor.OneMinusDstAlpha,
|
||||
GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => BlendFactor.DstColor,
|
||||
GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => BlendFactor.OneMinusDstColor,
|
||||
GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => BlendFactor.SrcAlphaSaturate,
|
||||
GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => BlendFactor.Src1Color,
|
||||
GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => BlendFactor.OneMinusSrc1Color,
|
||||
GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => BlendFactor.Src1Alpha,
|
||||
GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => BlendFactor.OneMinusSrc1Alpha,
|
||||
GAL.BlendFactor.ConstantColor => BlendFactor.ConstantColor,
|
||||
GAL.BlendFactor.OneMinusConstantColor => BlendFactor.OneMinusConstantColor,
|
||||
GAL.BlendFactor.ConstantAlpha => BlendFactor.ConstantAlpha,
|
||||
GAL.BlendFactor.OneMinusConstantAlpha => BlendFactor.OneMinusConstantAlpha,
|
||||
_ => LogInvalidAndReturn(factor, nameof(GAL.BlendFactor), BlendFactor.Zero),
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.AdvancedBlendOp op)
|
||||
public static BlendOp Convert(this AdvancedBlendOp op)
|
||||
{
|
||||
return op switch
|
||||
{
|
||||
GAL.AdvancedBlendOp.Zero => Silk.NET.Vulkan.BlendOp.ZeroExt,
|
||||
GAL.AdvancedBlendOp.Src => Silk.NET.Vulkan.BlendOp.SrcExt,
|
||||
GAL.AdvancedBlendOp.Dst => Silk.NET.Vulkan.BlendOp.DstExt,
|
||||
GAL.AdvancedBlendOp.SrcOver => Silk.NET.Vulkan.BlendOp.SrcOverExt,
|
||||
GAL.AdvancedBlendOp.DstOver => Silk.NET.Vulkan.BlendOp.DstOverExt,
|
||||
GAL.AdvancedBlendOp.SrcIn => Silk.NET.Vulkan.BlendOp.SrcInExt,
|
||||
GAL.AdvancedBlendOp.DstIn => Silk.NET.Vulkan.BlendOp.DstInExt,
|
||||
GAL.AdvancedBlendOp.SrcOut => Silk.NET.Vulkan.BlendOp.SrcOutExt,
|
||||
GAL.AdvancedBlendOp.DstOut => Silk.NET.Vulkan.BlendOp.DstOutExt,
|
||||
GAL.AdvancedBlendOp.SrcAtop => Silk.NET.Vulkan.BlendOp.SrcAtopExt,
|
||||
GAL.AdvancedBlendOp.DstAtop => Silk.NET.Vulkan.BlendOp.DstAtopExt,
|
||||
GAL.AdvancedBlendOp.Xor => Silk.NET.Vulkan.BlendOp.XorExt,
|
||||
GAL.AdvancedBlendOp.Plus => Silk.NET.Vulkan.BlendOp.PlusExt,
|
||||
GAL.AdvancedBlendOp.PlusClamped => Silk.NET.Vulkan.BlendOp.PlusClampedExt,
|
||||
GAL.AdvancedBlendOp.PlusClampedAlpha => Silk.NET.Vulkan.BlendOp.PlusClampedAlphaExt,
|
||||
GAL.AdvancedBlendOp.PlusDarker => Silk.NET.Vulkan.BlendOp.PlusDarkerExt,
|
||||
GAL.AdvancedBlendOp.Multiply => Silk.NET.Vulkan.BlendOp.MultiplyExt,
|
||||
GAL.AdvancedBlendOp.Screen => Silk.NET.Vulkan.BlendOp.ScreenExt,
|
||||
GAL.AdvancedBlendOp.Overlay => Silk.NET.Vulkan.BlendOp.OverlayExt,
|
||||
GAL.AdvancedBlendOp.Darken => Silk.NET.Vulkan.BlendOp.DarkenExt,
|
||||
GAL.AdvancedBlendOp.Lighten => Silk.NET.Vulkan.BlendOp.LightenExt,
|
||||
GAL.AdvancedBlendOp.ColorDodge => Silk.NET.Vulkan.BlendOp.ColordodgeExt,
|
||||
GAL.AdvancedBlendOp.ColorBurn => Silk.NET.Vulkan.BlendOp.ColorburnExt,
|
||||
GAL.AdvancedBlendOp.HardLight => Silk.NET.Vulkan.BlendOp.HardlightExt,
|
||||
GAL.AdvancedBlendOp.SoftLight => Silk.NET.Vulkan.BlendOp.SoftlightExt,
|
||||
GAL.AdvancedBlendOp.Difference => Silk.NET.Vulkan.BlendOp.DifferenceExt,
|
||||
GAL.AdvancedBlendOp.Minus => Silk.NET.Vulkan.BlendOp.MinusExt,
|
||||
GAL.AdvancedBlendOp.MinusClamped => Silk.NET.Vulkan.BlendOp.MinusClampedExt,
|
||||
GAL.AdvancedBlendOp.Exclusion => Silk.NET.Vulkan.BlendOp.ExclusionExt,
|
||||
GAL.AdvancedBlendOp.Contrast => Silk.NET.Vulkan.BlendOp.ContrastExt,
|
||||
GAL.AdvancedBlendOp.Invert => Silk.NET.Vulkan.BlendOp.InvertExt,
|
||||
GAL.AdvancedBlendOp.InvertRGB => Silk.NET.Vulkan.BlendOp.InvertRgbExt,
|
||||
GAL.AdvancedBlendOp.InvertOvg => Silk.NET.Vulkan.BlendOp.InvertOvgExt,
|
||||
GAL.AdvancedBlendOp.LinearDodge => Silk.NET.Vulkan.BlendOp.LineardodgeExt,
|
||||
GAL.AdvancedBlendOp.LinearBurn => Silk.NET.Vulkan.BlendOp.LinearburnExt,
|
||||
GAL.AdvancedBlendOp.VividLight => Silk.NET.Vulkan.BlendOp.VividlightExt,
|
||||
GAL.AdvancedBlendOp.LinearLight => Silk.NET.Vulkan.BlendOp.LinearlightExt,
|
||||
GAL.AdvancedBlendOp.PinLight => Silk.NET.Vulkan.BlendOp.PinlightExt,
|
||||
GAL.AdvancedBlendOp.HardMix => Silk.NET.Vulkan.BlendOp.HardmixExt,
|
||||
GAL.AdvancedBlendOp.Red => Silk.NET.Vulkan.BlendOp.RedExt,
|
||||
GAL.AdvancedBlendOp.Green => Silk.NET.Vulkan.BlendOp.GreenExt,
|
||||
GAL.AdvancedBlendOp.Blue => Silk.NET.Vulkan.BlendOp.BlueExt,
|
||||
GAL.AdvancedBlendOp.HslHue => Silk.NET.Vulkan.BlendOp.HslHueExt,
|
||||
GAL.AdvancedBlendOp.HslSaturation => Silk.NET.Vulkan.BlendOp.HslSaturationExt,
|
||||
GAL.AdvancedBlendOp.HslColor => Silk.NET.Vulkan.BlendOp.HslColorExt,
|
||||
GAL.AdvancedBlendOp.HslLuminosity => Silk.NET.Vulkan.BlendOp.HslLuminosityExt,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.AdvancedBlendOp), Silk.NET.Vulkan.BlendOp.Add)
|
||||
AdvancedBlendOp.Zero => BlendOp.ZeroExt,
|
||||
AdvancedBlendOp.Src => BlendOp.SrcExt,
|
||||
AdvancedBlendOp.Dst => BlendOp.DstExt,
|
||||
AdvancedBlendOp.SrcOver => BlendOp.SrcOverExt,
|
||||
AdvancedBlendOp.DstOver => BlendOp.DstOverExt,
|
||||
AdvancedBlendOp.SrcIn => BlendOp.SrcInExt,
|
||||
AdvancedBlendOp.DstIn => BlendOp.DstInExt,
|
||||
AdvancedBlendOp.SrcOut => BlendOp.SrcOutExt,
|
||||
AdvancedBlendOp.DstOut => BlendOp.DstOutExt,
|
||||
AdvancedBlendOp.SrcAtop => BlendOp.SrcAtopExt,
|
||||
AdvancedBlendOp.DstAtop => BlendOp.DstAtopExt,
|
||||
AdvancedBlendOp.Xor => BlendOp.XorExt,
|
||||
AdvancedBlendOp.Plus => BlendOp.PlusExt,
|
||||
AdvancedBlendOp.PlusClamped => BlendOp.PlusClampedExt,
|
||||
AdvancedBlendOp.PlusClampedAlpha => BlendOp.PlusClampedAlphaExt,
|
||||
AdvancedBlendOp.PlusDarker => BlendOp.PlusDarkerExt,
|
||||
AdvancedBlendOp.Multiply => BlendOp.MultiplyExt,
|
||||
AdvancedBlendOp.Screen => BlendOp.ScreenExt,
|
||||
AdvancedBlendOp.Overlay => BlendOp.OverlayExt,
|
||||
AdvancedBlendOp.Darken => BlendOp.DarkenExt,
|
||||
AdvancedBlendOp.Lighten => BlendOp.LightenExt,
|
||||
AdvancedBlendOp.ColorDodge => BlendOp.ColordodgeExt,
|
||||
AdvancedBlendOp.ColorBurn => BlendOp.ColorburnExt,
|
||||
AdvancedBlendOp.HardLight => BlendOp.HardlightExt,
|
||||
AdvancedBlendOp.SoftLight => BlendOp.SoftlightExt,
|
||||
AdvancedBlendOp.Difference => BlendOp.DifferenceExt,
|
||||
AdvancedBlendOp.Minus => BlendOp.MinusExt,
|
||||
AdvancedBlendOp.MinusClamped => BlendOp.MinusClampedExt,
|
||||
AdvancedBlendOp.Exclusion => BlendOp.ExclusionExt,
|
||||
AdvancedBlendOp.Contrast => BlendOp.ContrastExt,
|
||||
AdvancedBlendOp.Invert => BlendOp.InvertExt,
|
||||
AdvancedBlendOp.InvertRGB => BlendOp.InvertRgbExt,
|
||||
AdvancedBlendOp.InvertOvg => BlendOp.InvertOvgExt,
|
||||
AdvancedBlendOp.LinearDodge => BlendOp.LineardodgeExt,
|
||||
AdvancedBlendOp.LinearBurn => BlendOp.LinearburnExt,
|
||||
AdvancedBlendOp.VividLight => BlendOp.VividlightExt,
|
||||
AdvancedBlendOp.LinearLight => BlendOp.LinearlightExt,
|
||||
AdvancedBlendOp.PinLight => BlendOp.PinlightExt,
|
||||
AdvancedBlendOp.HardMix => BlendOp.HardmixExt,
|
||||
AdvancedBlendOp.Red => BlendOp.RedExt,
|
||||
AdvancedBlendOp.Green => BlendOp.GreenExt,
|
||||
AdvancedBlendOp.Blue => BlendOp.BlueExt,
|
||||
AdvancedBlendOp.HslHue => BlendOp.HslHueExt,
|
||||
AdvancedBlendOp.HslSaturation => BlendOp.HslSaturationExt,
|
||||
AdvancedBlendOp.HslColor => BlendOp.HslColorExt,
|
||||
AdvancedBlendOp.HslLuminosity => BlendOp.HslLuminosityExt,
|
||||
_ => LogInvalidAndReturn(op, nameof(AdvancedBlendOp), BlendOp.Add),
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.BlendOp Convert(this GAL.BlendOp op)
|
||||
public static BlendOp Convert(this GAL.BlendOp op)
|
||||
{
|
||||
return op switch
|
||||
{
|
||||
GAL.BlendOp.Add or GAL.BlendOp.AddGl => Silk.NET.Vulkan.BlendOp.Add,
|
||||
GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => Silk.NET.Vulkan.BlendOp.Subtract,
|
||||
GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => Silk.NET.Vulkan.BlendOp.ReverseSubtract,
|
||||
GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => Silk.NET.Vulkan.BlendOp.Min,
|
||||
GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => Silk.NET.Vulkan.BlendOp.Max,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.BlendOp), Silk.NET.Vulkan.BlendOp.Add)
|
||||
GAL.BlendOp.Add or GAL.BlendOp.AddGl => BlendOp.Add,
|
||||
GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => BlendOp.Subtract,
|
||||
GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => BlendOp.ReverseSubtract,
|
||||
GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => BlendOp.Min,
|
||||
GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => BlendOp.Max,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.BlendOp), BlendOp.Add),
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.BlendOverlapEXT Convert(this GAL.AdvancedBlendOverlap overlap)
|
||||
public static BlendOverlapEXT Convert(this AdvancedBlendOverlap overlap)
|
||||
{
|
||||
return overlap switch
|
||||
{
|
||||
GAL.AdvancedBlendOverlap.Uncorrelated => Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt,
|
||||
GAL.AdvancedBlendOverlap.Disjoint => Silk.NET.Vulkan.BlendOverlapEXT.DisjointExt,
|
||||
GAL.AdvancedBlendOverlap.Conjoint => Silk.NET.Vulkan.BlendOverlapEXT.ConjointExt,
|
||||
_ => LogInvalidAndReturn(overlap, nameof(GAL.AdvancedBlendOverlap), Silk.NET.Vulkan.BlendOverlapEXT.UncorrelatedExt)
|
||||
AdvancedBlendOverlap.Uncorrelated => BlendOverlapEXT.UncorrelatedExt,
|
||||
AdvancedBlendOverlap.Disjoint => BlendOverlapEXT.DisjointExt,
|
||||
AdvancedBlendOverlap.Conjoint => BlendOverlapEXT.ConjointExt,
|
||||
_ => LogInvalidAndReturn(overlap, nameof(AdvancedBlendOverlap), BlendOverlapEXT.UncorrelatedExt),
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.CompareOp Convert(this GAL.CompareOp op)
|
||||
public static CompareOp Convert(this GAL.CompareOp op)
|
||||
{
|
||||
return op switch
|
||||
{
|
||||
GAL.CompareOp.Never or GAL.CompareOp.NeverGl => Silk.NET.Vulkan.CompareOp.Never,
|
||||
GAL.CompareOp.Less or GAL.CompareOp.LessGl => Silk.NET.Vulkan.CompareOp.Less,
|
||||
GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => Silk.NET.Vulkan.CompareOp.Equal,
|
||||
GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => Silk.NET.Vulkan.CompareOp.LessOrEqual,
|
||||
GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => Silk.NET.Vulkan.CompareOp.Greater,
|
||||
GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => Silk.NET.Vulkan.CompareOp.NotEqual,
|
||||
GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => Silk.NET.Vulkan.CompareOp.GreaterOrEqual,
|
||||
GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => Silk.NET.Vulkan.CompareOp.Always,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), Silk.NET.Vulkan.CompareOp.Never)
|
||||
GAL.CompareOp.Never or GAL.CompareOp.NeverGl => CompareOp.Never,
|
||||
GAL.CompareOp.Less or GAL.CompareOp.LessGl => CompareOp.Less,
|
||||
GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => CompareOp.Equal,
|
||||
GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => CompareOp.LessOrEqual,
|
||||
GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => CompareOp.Greater,
|
||||
GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => CompareOp.NotEqual,
|
||||
GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => CompareOp.GreaterOrEqual,
|
||||
GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => CompareOp.Always,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), CompareOp.Never),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -230,29 +238,29 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Face.Back => CullModeFlags.BackBit,
|
||||
Face.Front => CullModeFlags.FrontBit,
|
||||
Face.FrontAndBack => CullModeFlags.FrontAndBack,
|
||||
_ => LogInvalidAndReturn(face, nameof(Face), CullModeFlags.BackBit)
|
||||
_ => LogInvalidAndReturn(face, nameof(Face), CullModeFlags.BackBit),
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.FrontFace Convert(this GAL.FrontFace frontFace)
|
||||
public static FrontFace Convert(this GAL.FrontFace frontFace)
|
||||
{
|
||||
// Flipped to account for origin differences.
|
||||
return frontFace switch
|
||||
{
|
||||
GAL.FrontFace.Clockwise => Silk.NET.Vulkan.FrontFace.CounterClockwise,
|
||||
GAL.FrontFace.CounterClockwise => Silk.NET.Vulkan.FrontFace.Clockwise,
|
||||
_ => LogInvalidAndReturn(frontFace, nameof(GAL.FrontFace), Silk.NET.Vulkan.FrontFace.Clockwise)
|
||||
GAL.FrontFace.Clockwise => FrontFace.CounterClockwise,
|
||||
GAL.FrontFace.CounterClockwise => FrontFace.Clockwise,
|
||||
_ => LogInvalidAndReturn(frontFace, nameof(GAL.FrontFace), FrontFace.Clockwise),
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.IndexType Convert(this GAL.IndexType type)
|
||||
public static IndexType Convert(this GAL.IndexType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
GAL.IndexType.UByte => Silk.NET.Vulkan.IndexType.Uint8Ext,
|
||||
GAL.IndexType.UShort => Silk.NET.Vulkan.IndexType.Uint16,
|
||||
GAL.IndexType.UInt => Silk.NET.Vulkan.IndexType.Uint32,
|
||||
_ => LogInvalidAndReturn(type, nameof(GAL.IndexType), Silk.NET.Vulkan.IndexType.Uint16)
|
||||
GAL.IndexType.UByte => IndexType.Uint8Ext,
|
||||
GAL.IndexType.UShort => IndexType.Uint16,
|
||||
GAL.IndexType.UInt => IndexType.Uint32,
|
||||
_ => LogInvalidAndReturn(type, nameof(GAL.IndexType), IndexType.Uint16),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -262,7 +270,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
MagFilter.Nearest => Filter.Nearest,
|
||||
MagFilter.Linear => Filter.Linear,
|
||||
_ => LogInvalidAndReturn(filter, nameof(MagFilter), Filter.Nearest)
|
||||
_ => LogInvalidAndReturn(filter, nameof(MagFilter), Filter.Nearest),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -276,45 +284,45 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MinFilter.LinearMipmapNearest => (Filter.Linear, SamplerMipmapMode.Nearest),
|
||||
MinFilter.NearestMipmapLinear => (Filter.Nearest, SamplerMipmapMode.Linear),
|
||||
MinFilter.LinearMipmapLinear => (Filter.Linear, SamplerMipmapMode.Linear),
|
||||
_ => LogInvalidAndReturn(filter, nameof(MinFilter), (Filter.Nearest, SamplerMipmapMode.Nearest))
|
||||
_ => LogInvalidAndReturn(filter, nameof(MinFilter), (Filter.Nearest, SamplerMipmapMode.Nearest)),
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.PrimitiveTopology Convert(this GAL.PrimitiveTopology topology)
|
||||
public static PrimitiveTopology Convert(this GAL.PrimitiveTopology topology)
|
||||
{
|
||||
return topology switch
|
||||
{
|
||||
GAL.PrimitiveTopology.Points => Silk.NET.Vulkan.PrimitiveTopology.PointList,
|
||||
GAL.PrimitiveTopology.Lines => Silk.NET.Vulkan.PrimitiveTopology.LineList,
|
||||
GAL.PrimitiveTopology.LineStrip => Silk.NET.Vulkan.PrimitiveTopology.LineStrip,
|
||||
GAL.PrimitiveTopology.Triangles => Silk.NET.Vulkan.PrimitiveTopology.TriangleList,
|
||||
GAL.PrimitiveTopology.TriangleStrip => Silk.NET.Vulkan.PrimitiveTopology.TriangleStrip,
|
||||
GAL.PrimitiveTopology.TriangleFan => Silk.NET.Vulkan.PrimitiveTopology.TriangleFan,
|
||||
GAL.PrimitiveTopology.LinesAdjacency => Silk.NET.Vulkan.PrimitiveTopology.LineListWithAdjacency,
|
||||
GAL.PrimitiveTopology.LineStripAdjacency => Silk.NET.Vulkan.PrimitiveTopology.LineStripWithAdjacency,
|
||||
GAL.PrimitiveTopology.TrianglesAdjacency => Silk.NET.Vulkan.PrimitiveTopology.TriangleListWithAdjacency,
|
||||
GAL.PrimitiveTopology.TriangleStripAdjacency => Silk.NET.Vulkan.PrimitiveTopology.TriangleStripWithAdjacency,
|
||||
GAL.PrimitiveTopology.Patches => Silk.NET.Vulkan.PrimitiveTopology.PatchList,
|
||||
GAL.PrimitiveTopology.Polygon => Silk.NET.Vulkan.PrimitiveTopology.TriangleFan,
|
||||
GAL.PrimitiveTopology.Points => PrimitiveTopology.PointList,
|
||||
GAL.PrimitiveTopology.Lines => PrimitiveTopology.LineList,
|
||||
GAL.PrimitiveTopology.LineStrip => PrimitiveTopology.LineStrip,
|
||||
GAL.PrimitiveTopology.Triangles => PrimitiveTopology.TriangleList,
|
||||
GAL.PrimitiveTopology.TriangleStrip => PrimitiveTopology.TriangleStrip,
|
||||
GAL.PrimitiveTopology.TriangleFan => PrimitiveTopology.TriangleFan,
|
||||
GAL.PrimitiveTopology.LinesAdjacency => PrimitiveTopology.LineListWithAdjacency,
|
||||
GAL.PrimitiveTopology.LineStripAdjacency => PrimitiveTopology.LineStripWithAdjacency,
|
||||
GAL.PrimitiveTopology.TrianglesAdjacency => PrimitiveTopology.TriangleListWithAdjacency,
|
||||
GAL.PrimitiveTopology.TriangleStripAdjacency => PrimitiveTopology.TriangleStripWithAdjacency,
|
||||
GAL.PrimitiveTopology.Patches => PrimitiveTopology.PatchList,
|
||||
GAL.PrimitiveTopology.Polygon => PrimitiveTopology.TriangleFan,
|
||||
GAL.PrimitiveTopology.Quads => throw new NotSupportedException("Quad topology is not available in Vulkan."),
|
||||
GAL.PrimitiveTopology.QuadStrip => throw new NotSupportedException("QuadStrip topology is not available in Vulkan."),
|
||||
_ => LogInvalidAndReturn(topology, nameof(GAL.PrimitiveTopology), Silk.NET.Vulkan.PrimitiveTopology.TriangleList)
|
||||
_ => LogInvalidAndReturn(topology, nameof(GAL.PrimitiveTopology), PrimitiveTopology.TriangleList),
|
||||
};
|
||||
}
|
||||
|
||||
public static Silk.NET.Vulkan.StencilOp Convert(this GAL.StencilOp op)
|
||||
public static StencilOp Convert(this GAL.StencilOp op)
|
||||
{
|
||||
return op switch
|
||||
{
|
||||
GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => Silk.NET.Vulkan.StencilOp.Keep,
|
||||
GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => Silk.NET.Vulkan.StencilOp.Zero,
|
||||
GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => Silk.NET.Vulkan.StencilOp.Replace,
|
||||
GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => Silk.NET.Vulkan.StencilOp.IncrementAndClamp,
|
||||
GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => Silk.NET.Vulkan.StencilOp.DecrementAndClamp,
|
||||
GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => Silk.NET.Vulkan.StencilOp.Invert,
|
||||
GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => Silk.NET.Vulkan.StencilOp.IncrementAndWrap,
|
||||
GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => Silk.NET.Vulkan.StencilOp.DecrementAndWrap,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), Silk.NET.Vulkan.StencilOp.Keep)
|
||||
GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => StencilOp.Keep,
|
||||
GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => StencilOp.Zero,
|
||||
GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => StencilOp.Replace,
|
||||
GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => StencilOp.IncrementAndClamp,
|
||||
GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => StencilOp.DecrementAndClamp,
|
||||
GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => StencilOp.Invert,
|
||||
GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => StencilOp.IncrementAndWrap,
|
||||
GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => StencilOp.DecrementAndWrap,
|
||||
_ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), StencilOp.Keep),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -328,7 +336,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SwizzleComponent.Green => ComponentSwizzle.G,
|
||||
SwizzleComponent.Blue => ComponentSwizzle.B,
|
||||
SwizzleComponent.Alpha => ComponentSwizzle.A,
|
||||
_ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), ComponentSwizzle.Zero)
|
||||
_ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), ComponentSwizzle.Zero),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -345,7 +353,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Target.Cubemap or
|
||||
Target.CubemapArray => ImageType.Type2D,
|
||||
Target.Texture3D => ImageType.Type3D,
|
||||
_ => LogInvalidAndReturn(target, nameof(Target), ImageType.Type2D)
|
||||
_ => LogInvalidAndReturn(target, nameof(Target), ImageType.Type2D),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -360,33 +368,33 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Target.Texture2DArray => ImageViewType.Type2DArray,
|
||||
Target.Cubemap => ImageViewType.TypeCube,
|
||||
Target.CubemapArray => ImageViewType.TypeCubeArray,
|
||||
_ => LogInvalidAndReturn(target, nameof(Target), ImageViewType.Type2D)
|
||||
_ => LogInvalidAndReturn(target, nameof(Target), ImageViewType.Type2D),
|
||||
};
|
||||
}
|
||||
|
||||
public static ImageAspectFlags ConvertAspectFlags(this GAL.Format format)
|
||||
public static ImageAspectFlags ConvertAspectFlags(this Format format)
|
||||
{
|
||||
return format switch
|
||||
{
|
||||
GAL.Format.D16Unorm or GAL.Format.D32Float => ImageAspectFlags.DepthBit,
|
||||
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
GAL.Format.D24UnormS8Uint or
|
||||
GAL.Format.D32FloatS8Uint or
|
||||
GAL.Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
||||
_ => ImageAspectFlags.ColorBit
|
||||
Format.D16Unorm or Format.D32Float => ImageAspectFlags.DepthBit,
|
||||
Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
Format.D24UnormS8Uint or
|
||||
Format.D32FloatS8Uint or
|
||||
Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
||||
_ => ImageAspectFlags.ColorBit,
|
||||
};
|
||||
}
|
||||
|
||||
public static ImageAspectFlags ConvertAspectFlags(this GAL.Format format, DepthStencilMode depthStencilMode)
|
||||
public static ImageAspectFlags ConvertAspectFlags(this Format format, DepthStencilMode depthStencilMode)
|
||||
{
|
||||
return format switch
|
||||
{
|
||||
GAL.Format.D16Unorm or GAL.Format.D32Float => ImageAspectFlags.DepthBit,
|
||||
GAL.Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
GAL.Format.D24UnormS8Uint or
|
||||
GAL.Format.D32FloatS8Uint or
|
||||
GAL.Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
|
||||
_ => ImageAspectFlags.ColorBit
|
||||
Format.D16Unorm or Format.D32Float => ImageAspectFlags.DepthBit,
|
||||
Format.S8Uint => ImageAspectFlags.StencilBit,
|
||||
Format.D24UnormS8Uint or
|
||||
Format.D32FloatS8Uint or
|
||||
Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
|
||||
_ => ImageAspectFlags.ColorBit,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -410,7 +418,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
LogicalOp.OrInverted => LogicOp.OrInverted,
|
||||
LogicalOp.Nand => LogicOp.Nand,
|
||||
LogicalOp.Set => LogicOp.Set,
|
||||
_ => LogInvalidAndReturn(op, nameof(LogicalOp), LogicOp.Copy)
|
||||
_ => LogInvalidAndReturn(op, nameof(LogicalOp), LogicOp.Copy),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -419,7 +427,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return access switch
|
||||
{
|
||||
BufferAccess.FlushPersistent => BufferAllocationType.HostMapped,
|
||||
_ => BufferAllocationType.Auto
|
||||
_ => BufferAllocationType.Auto,
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -17,9 +17,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_api = api;
|
||||
_device = device;
|
||||
|
||||
var fenceCreateInfo = new FenceCreateInfo()
|
||||
var fenceCreateInfo = new FenceCreateInfo
|
||||
{
|
||||
SType = StructureType.FenceCreateInfo
|
||||
SType = StructureType.FenceCreateInfo,
|
||||
};
|
||||
|
||||
api.CreateFence(device, in fenceCreateInfo, null, out _fence).ThrowOnError();
|
||||
@@ -70,7 +70,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Span<Fence> fences = stackalloc Fence[]
|
||||
{
|
||||
_fence
|
||||
_fence,
|
||||
};
|
||||
|
||||
FenceHelper.WaitAllIndefinitely(_api, _device, fences);
|
||||
@@ -80,7 +80,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Span<Fence> fences = stackalloc Fence[]
|
||||
{
|
||||
_fence
|
||||
_fence,
|
||||
};
|
||||
|
||||
return FenceHelper.AllSignaled(_api, _device, fences);
|
||||
|
@@ -2,6 +2,7 @@ using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
@@ -19,15 +20,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_api = api;
|
||||
_physicalDevice = physicalDevice;
|
||||
|
||||
int totalFormats = Enum.GetNames(typeof(GAL.Format)).Length;
|
||||
int totalFormats = Enum.GetNames(typeof(Format)).Length;
|
||||
|
||||
_bufferTable = new FormatFeatureFlags[totalFormats];
|
||||
_optimalTable = new FormatFeatureFlags[totalFormats];
|
||||
}
|
||||
|
||||
public bool BufferFormatsSupport(FormatFeatureFlags flags, params GAL.Format[] formats)
|
||||
public bool BufferFormatsSupport(FormatFeatureFlags flags, params Format[] formats)
|
||||
{
|
||||
foreach (GAL.Format format in formats)
|
||||
foreach (Format format in formats)
|
||||
{
|
||||
if (!BufferFormatSupports(flags, format))
|
||||
{
|
||||
@@ -38,9 +39,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OptimalFormatsSupport(FormatFeatureFlags flags, params GAL.Format[] formats)
|
||||
public bool OptimalFormatsSupport(FormatFeatureFlags flags, params Format[] formats)
|
||||
{
|
||||
foreach (GAL.Format format in formats)
|
||||
foreach (Format format in formats)
|
||||
{
|
||||
if (!OptimalFormatSupports(flags, format))
|
||||
{
|
||||
@@ -51,7 +52,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool BufferFormatSupports(FormatFeatureFlags flags, GAL.Format format)
|
||||
public bool BufferFormatSupports(FormatFeatureFlags flags, Format format)
|
||||
{
|
||||
var formatFeatureFlags = _bufferTable[(int)format];
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return (fp.BufferFeatures & flags) == flags;
|
||||
}
|
||||
|
||||
public bool OptimalFormatSupports(FormatFeatureFlags flags, GAL.Format format)
|
||||
public bool OptimalFormatSupports(FormatFeatureFlags flags, Format format)
|
||||
{
|
||||
var formatFeatureFlags = _optimalTable[(int)format];
|
||||
|
||||
@@ -86,7 +87,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return (formatFeatureFlags & flags) == flags;
|
||||
}
|
||||
|
||||
public VkFormat ConvertToVkFormat(GAL.Format srcFormat)
|
||||
public VkFormat ConvertToVkFormat(Format srcFormat)
|
||||
{
|
||||
var format = FormatTable.GetFormat(srcFormat);
|
||||
|
||||
@@ -115,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
format = VkFormat.D32SfloatS8Uint;
|
||||
}
|
||||
else if (srcFormat == GAL.Format.R4G4B4A4Unorm)
|
||||
else if (srcFormat == Format.R4G4B4A4Unorm)
|
||||
{
|
||||
format = VkFormat.R4G4B4A4UnormPack16;
|
||||
}
|
||||
@@ -128,7 +129,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return format;
|
||||
}
|
||||
|
||||
public VkFormat ConvertToVertexVkFormat(GAL.Format srcFormat)
|
||||
public VkFormat ConvertToVertexVkFormat(Format srcFormat)
|
||||
{
|
||||
var format = FormatTable.GetFormat(srcFormat);
|
||||
|
||||
@@ -138,13 +139,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// The format is not supported. Can we convert it to an alternative format?
|
||||
switch (srcFormat)
|
||||
{
|
||||
case GAL.Format.R16G16B16Float:
|
||||
case Format.R16G16B16Float:
|
||||
format = VkFormat.R16G16B16A16Sfloat;
|
||||
break;
|
||||
case GAL.Format.R16G16B16Sint:
|
||||
case Format.R16G16B16Sint:
|
||||
format = VkFormat.R16G16B16A16Sint;
|
||||
break;
|
||||
case GAL.Format.R16G16B16Uint:
|
||||
case Format.R16G16B16Uint:
|
||||
format = VkFormat.R16G16B16A16Uint;
|
||||
break;
|
||||
default:
|
||||
@@ -156,16 +157,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return format;
|
||||
}
|
||||
|
||||
public static bool IsD24S8(GAL.Format format)
|
||||
public static bool IsD24S8(Format format)
|
||||
{
|
||||
return format == GAL.Format.D24UnormS8Uint || format == GAL.Format.S8UintD24Unorm;
|
||||
return format == Format.D24UnormS8Uint || format == Format.S8UintD24Unorm;
|
||||
}
|
||||
|
||||
private static bool IsRGB16IntFloat(GAL.Format format)
|
||||
private static bool IsRGB16IntFloat(Format format)
|
||||
{
|
||||
return format == GAL.Format.R16G16B16Float ||
|
||||
format == GAL.Format.R16G16B16Sint ||
|
||||
format == GAL.Format.R16G16B16Uint;
|
||||
return format == Format.R16G16B16Float ||
|
||||
format == Format.R16G16B16Sint ||
|
||||
format == Format.R16G16B16Uint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
_table = new VkFormat[Enum.GetNames(typeof(Format)).Length];
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
Add(Format.R8Unorm, VkFormat.R8Unorm);
|
||||
Add(Format.R8Snorm, VkFormat.R8SNorm);
|
||||
Add(Format.R8Uint, VkFormat.R8Uint);
|
||||
@@ -157,6 +158,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Add(Format.A1B5G5R5Unorm, VkFormat.R5G5B5A1UnormPack16);
|
||||
Add(Format.B8G8R8A8Unorm, VkFormat.B8G8R8A8Unorm);
|
||||
Add(Format.B8G8R8A8Srgb, VkFormat.B8G8R8A8Srgb);
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
private static void Add(Format format, VkFormat vkFormat)
|
||||
@@ -175,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Format.R8G8B8A8Srgb => Format.R8G8B8A8Unorm,
|
||||
Format.B8G8R8A8Srgb => Format.B8G8R8A8Unorm,
|
||||
_ => format
|
||||
_ => format,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -280,121 +282,61 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public static VkFormat DropLastComponent(VkFormat format)
|
||||
{
|
||||
switch (format)
|
||||
return format switch
|
||||
{
|
||||
case VkFormat.R8G8Unorm:
|
||||
return VkFormat.R8Unorm;
|
||||
case VkFormat.R8G8SNorm:
|
||||
return VkFormat.R8SNorm;
|
||||
case VkFormat.R8G8Uint:
|
||||
return VkFormat.R8Uint;
|
||||
case VkFormat.R8G8Sint:
|
||||
return VkFormat.R8Sint;
|
||||
case VkFormat.R8G8Uscaled:
|
||||
return VkFormat.R8Uscaled;
|
||||
case VkFormat.R8G8Sscaled:
|
||||
return VkFormat.R8Sscaled;
|
||||
|
||||
case VkFormat.R8G8B8Unorm:
|
||||
return VkFormat.R8G8Unorm;
|
||||
case VkFormat.R8G8B8SNorm:
|
||||
return VkFormat.R8G8SNorm;
|
||||
case VkFormat.R8G8B8Uint:
|
||||
return VkFormat.R8G8Uint;
|
||||
case VkFormat.R8G8B8Sint:
|
||||
return VkFormat.R8G8Sint;
|
||||
case VkFormat.R8G8B8Uscaled:
|
||||
return VkFormat.R8G8Uscaled;
|
||||
case VkFormat.R8G8B8Sscaled:
|
||||
return VkFormat.R8G8Sscaled;
|
||||
|
||||
case VkFormat.R8G8B8A8Unorm:
|
||||
return VkFormat.R8G8B8Unorm;
|
||||
case VkFormat.R8G8B8A8SNorm:
|
||||
return VkFormat.R8G8B8SNorm;
|
||||
case VkFormat.R8G8B8A8Uint:
|
||||
return VkFormat.R8G8B8Uint;
|
||||
case VkFormat.R8G8B8A8Sint:
|
||||
return VkFormat.R8G8B8Sint;
|
||||
case VkFormat.R8G8B8A8Srgb:
|
||||
return VkFormat.R8G8B8Srgb;
|
||||
case VkFormat.R8G8B8A8Uscaled:
|
||||
return VkFormat.R8G8B8Uscaled;
|
||||
case VkFormat.R8G8B8A8Sscaled:
|
||||
return VkFormat.R8G8B8Sscaled;
|
||||
case VkFormat.B8G8R8A8Unorm:
|
||||
return VkFormat.B8G8R8Unorm;
|
||||
case VkFormat.B8G8R8A8Srgb:
|
||||
return VkFormat.B8G8R8Srgb;
|
||||
|
||||
case VkFormat.R16G16Sfloat:
|
||||
return VkFormat.R16Sfloat;
|
||||
case VkFormat.R16G16Unorm:
|
||||
return VkFormat.R16Unorm;
|
||||
case VkFormat.R16G16SNorm:
|
||||
return VkFormat.R16SNorm;
|
||||
case VkFormat.R16G16Uint:
|
||||
return VkFormat.R16Uint;
|
||||
case VkFormat.R16G16Sint:
|
||||
return VkFormat.R16Sint;
|
||||
case VkFormat.R16G16Uscaled:
|
||||
return VkFormat.R16Uscaled;
|
||||
case VkFormat.R16G16Sscaled:
|
||||
return VkFormat.R16Sscaled;
|
||||
|
||||
case VkFormat.R16G16B16Sfloat:
|
||||
return VkFormat.R16G16Sfloat;
|
||||
case VkFormat.R16G16B16Unorm:
|
||||
return VkFormat.R16G16Unorm;
|
||||
case VkFormat.R16G16B16SNorm:
|
||||
return VkFormat.R16G16SNorm;
|
||||
case VkFormat.R16G16B16Uint:
|
||||
return VkFormat.R16G16Uint;
|
||||
case VkFormat.R16G16B16Sint:
|
||||
return VkFormat.R16G16Sint;
|
||||
case VkFormat.R16G16B16Uscaled:
|
||||
return VkFormat.R16G16Uscaled;
|
||||
case VkFormat.R16G16B16Sscaled:
|
||||
return VkFormat.R16G16Sscaled;
|
||||
|
||||
case VkFormat.R16G16B16A16Sfloat:
|
||||
return VkFormat.R16G16B16Sfloat;
|
||||
case VkFormat.R16G16B16A16Unorm:
|
||||
return VkFormat.R16G16B16Unorm;
|
||||
case VkFormat.R16G16B16A16SNorm:
|
||||
return VkFormat.R16G16B16SNorm;
|
||||
case VkFormat.R16G16B16A16Uint:
|
||||
return VkFormat.R16G16B16Uint;
|
||||
case VkFormat.R16G16B16A16Sint:
|
||||
return VkFormat.R16G16B16Sint;
|
||||
case VkFormat.R16G16B16A16Uscaled:
|
||||
return VkFormat.R16G16B16Uscaled;
|
||||
case VkFormat.R16G16B16A16Sscaled:
|
||||
return VkFormat.R16G16B16Sscaled;
|
||||
|
||||
case VkFormat.R32G32Sfloat:
|
||||
return VkFormat.R32Sfloat;
|
||||
case VkFormat.R32G32Uint:
|
||||
return VkFormat.R32Uint;
|
||||
case VkFormat.R32G32Sint:
|
||||
return VkFormat.R32Sint;
|
||||
|
||||
case VkFormat.R32G32B32Sfloat:
|
||||
return VkFormat.R32G32Sfloat;
|
||||
case VkFormat.R32G32B32Uint:
|
||||
return VkFormat.R32G32Uint;
|
||||
case VkFormat.R32G32B32Sint:
|
||||
return VkFormat.R32G32Sint;
|
||||
|
||||
case VkFormat.R32G32B32A32Sfloat:
|
||||
return VkFormat.R32G32B32Sfloat;
|
||||
case VkFormat.R32G32B32A32Uint:
|
||||
return VkFormat.R32G32B32Uint;
|
||||
case VkFormat.R32G32B32A32Sint:
|
||||
return VkFormat.R32G32B32Sint;
|
||||
}
|
||||
|
||||
return format;
|
||||
VkFormat.R8G8Unorm => VkFormat.R8Unorm,
|
||||
VkFormat.R8G8SNorm => VkFormat.R8SNorm,
|
||||
VkFormat.R8G8Uint => VkFormat.R8Uint,
|
||||
VkFormat.R8G8Sint => VkFormat.R8Sint,
|
||||
VkFormat.R8G8Uscaled => VkFormat.R8Uscaled,
|
||||
VkFormat.R8G8Sscaled => VkFormat.R8Sscaled,
|
||||
VkFormat.R8G8B8Unorm => VkFormat.R8G8Unorm,
|
||||
VkFormat.R8G8B8SNorm => VkFormat.R8G8SNorm,
|
||||
VkFormat.R8G8B8Uint => VkFormat.R8G8Uint,
|
||||
VkFormat.R8G8B8Sint => VkFormat.R8G8Sint,
|
||||
VkFormat.R8G8B8Uscaled => VkFormat.R8G8Uscaled,
|
||||
VkFormat.R8G8B8Sscaled => VkFormat.R8G8Sscaled,
|
||||
VkFormat.R8G8B8A8Unorm => VkFormat.R8G8B8Unorm,
|
||||
VkFormat.R8G8B8A8SNorm => VkFormat.R8G8B8SNorm,
|
||||
VkFormat.R8G8B8A8Uint => VkFormat.R8G8B8Uint,
|
||||
VkFormat.R8G8B8A8Sint => VkFormat.R8G8B8Sint,
|
||||
VkFormat.R8G8B8A8Srgb => VkFormat.R8G8B8Srgb,
|
||||
VkFormat.R8G8B8A8Uscaled => VkFormat.R8G8B8Uscaled,
|
||||
VkFormat.R8G8B8A8Sscaled => VkFormat.R8G8B8Sscaled,
|
||||
VkFormat.B8G8R8A8Unorm => VkFormat.B8G8R8Unorm,
|
||||
VkFormat.B8G8R8A8Srgb => VkFormat.B8G8R8Srgb,
|
||||
VkFormat.R16G16Sfloat => VkFormat.R16Sfloat,
|
||||
VkFormat.R16G16Unorm => VkFormat.R16Unorm,
|
||||
VkFormat.R16G16SNorm => VkFormat.R16SNorm,
|
||||
VkFormat.R16G16Uint => VkFormat.R16Uint,
|
||||
VkFormat.R16G16Sint => VkFormat.R16Sint,
|
||||
VkFormat.R16G16Uscaled => VkFormat.R16Uscaled,
|
||||
VkFormat.R16G16Sscaled => VkFormat.R16Sscaled,
|
||||
VkFormat.R16G16B16Sfloat => VkFormat.R16G16Sfloat,
|
||||
VkFormat.R16G16B16Unorm => VkFormat.R16G16Unorm,
|
||||
VkFormat.R16G16B16SNorm => VkFormat.R16G16SNorm,
|
||||
VkFormat.R16G16B16Uint => VkFormat.R16G16Uint,
|
||||
VkFormat.R16G16B16Sint => VkFormat.R16G16Sint,
|
||||
VkFormat.R16G16B16Uscaled => VkFormat.R16G16Uscaled,
|
||||
VkFormat.R16G16B16Sscaled => VkFormat.R16G16Sscaled,
|
||||
VkFormat.R16G16B16A16Sfloat => VkFormat.R16G16B16Sfloat,
|
||||
VkFormat.R16G16B16A16Unorm => VkFormat.R16G16B16Unorm,
|
||||
VkFormat.R16G16B16A16SNorm => VkFormat.R16G16B16SNorm,
|
||||
VkFormat.R16G16B16A16Uint => VkFormat.R16G16B16Uint,
|
||||
VkFormat.R16G16B16A16Sint => VkFormat.R16G16B16Sint,
|
||||
VkFormat.R16G16B16A16Uscaled => VkFormat.R16G16B16Uscaled,
|
||||
VkFormat.R16G16B16A16Sscaled => VkFormat.R16G16B16Sscaled,
|
||||
VkFormat.R32G32Sfloat => VkFormat.R32Sfloat,
|
||||
VkFormat.R32G32Uint => VkFormat.R32Uint,
|
||||
VkFormat.R32G32Sint => VkFormat.R32Sint,
|
||||
VkFormat.R32G32B32Sfloat => VkFormat.R32G32Sfloat,
|
||||
VkFormat.R32G32B32Uint => VkFormat.R32G32Uint,
|
||||
VkFormat.R32G32B32Sint => VkFormat.R32G32Sint,
|
||||
VkFormat.R32G32B32A32Sfloat => VkFormat.R32G32B32Sfloat,
|
||||
VkFormat.R32G32B32A32Uint => VkFormat.R32G32B32Uint,
|
||||
VkFormat.R32G32B32A32Sint => VkFormat.R32G32B32Sint,
|
||||
_ => format,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Auto<DisposableImageView>[] _attachments;
|
||||
private readonly TextureView[] _colors;
|
||||
private readonly TextureView _depthStencil;
|
||||
private uint _validColorAttachments;
|
||||
private readonly uint _validColorAttachments;
|
||||
|
||||
public uint Width { get; }
|
||||
public uint Height { get; }
|
||||
@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public uint AttachmentIntegerFormatMask { get; }
|
||||
|
||||
public int AttachmentsCount { get; }
|
||||
public int MaxColorAttachmentIndex => AttachmentIndices.Length > 0 ? AttachmentIndices[AttachmentIndices.Length - 1] : -1;
|
||||
public int MaxColorAttachmentIndex => AttachmentIndices.Length > 0 ? AttachmentIndices[^1] : -1;
|
||||
public bool HasDepthStencil { get; }
|
||||
public int ColorAttachmentsCount => AttachmentsCount - (HasDepthStencil ? 1 : 0);
|
||||
|
||||
@@ -158,7 +158,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
return ComponentType.SignedInteger;
|
||||
}
|
||||
else if (format.IsUint())
|
||||
|
||||
if (format.IsUint())
|
||||
{
|
||||
return ComponentType.UnsignedInteger;
|
||||
}
|
||||
@@ -196,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
attachments[i] = _attachments[i].Get(cbs).Value;
|
||||
}
|
||||
|
||||
var framebufferCreateInfo = new FramebufferCreateInfo()
|
||||
var framebufferCreateInfo = new FramebufferCreateInfo
|
||||
{
|
||||
SType = StructureType.FramebufferCreateInfo,
|
||||
RenderPass = renderPass.Get(cbs).Value,
|
||||
@@ -204,7 +205,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PAttachments = attachments,
|
||||
Width = Width,
|
||||
Height = Height,
|
||||
Layers = Layers
|
||||
Layers = Layers,
|
||||
};
|
||||
|
||||
api.CreateFramebuffer(_device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
||||
|
@@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
NoTriangleFans = 1,
|
||||
NoPointMode = 1 << 1,
|
||||
No3DImageView = 1 << 2,
|
||||
NoLodBias = 1 << 3
|
||||
NoLodBias = 1 << 3,
|
||||
}
|
||||
|
||||
readonly struct HardwareCapabilities
|
||||
|
@@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
bool Equals(ref T other);
|
||||
}
|
||||
|
||||
class HashTableSlim<K, V> where K : IRefEquatable<K>
|
||||
class HashTableSlim<TKey, TValue> where TKey : IRefEquatable<TKey>
|
||||
{
|
||||
private const int TotalBuckets = 16; // Must be power of 2
|
||||
private const int TotalBucketsMask = TotalBuckets - 1;
|
||||
@@ -16,13 +16,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private struct Entry
|
||||
{
|
||||
public int Hash;
|
||||
public K Key;
|
||||
public V Value;
|
||||
public TKey Key;
|
||||
public TValue Value;
|
||||
}
|
||||
|
||||
private readonly Entry[][] _hashTable = new Entry[TotalBuckets][];
|
||||
|
||||
public IEnumerable<K> Keys
|
||||
public IEnumerable<TKey> Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -39,7 +39,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<V> Values
|
||||
public IEnumerable<TValue> Values
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -56,13 +56,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(ref K key, V value)
|
||||
public void Add(ref TKey key, TValue value)
|
||||
{
|
||||
var entry = new Entry()
|
||||
var entry = new Entry
|
||||
{
|
||||
Hash = key.GetHashCode(),
|
||||
Key = key,
|
||||
Value = value
|
||||
Value = value,
|
||||
};
|
||||
|
||||
int hashCode = key.GetHashCode();
|
||||
@@ -79,14 +79,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
else
|
||||
{
|
||||
_hashTable[bucketIndex] = new Entry[]
|
||||
_hashTable[bucketIndex] = new[]
|
||||
{
|
||||
entry
|
||||
entry,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetValue(ref K key, out V value)
|
||||
public bool TryGetValue(ref TKey key, out TValue value)
|
||||
{
|
||||
int hashCode = key.GetHashCode();
|
||||
|
||||
|
@@ -6,6 +6,12 @@ using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
using StencilOp = Ryujinx.Graphics.GAL.StencilOp;
|
||||
using Viewport = Ryujinx.Graphics.GAL.Viewport;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
@@ -14,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Float,
|
||||
SignedInteger,
|
||||
UnsignedInteger
|
||||
UnsignedInteger,
|
||||
}
|
||||
|
||||
class HelperShader : IDisposable
|
||||
@@ -52,8 +58,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_pipeline = new PipelineHelperShader(gd, device);
|
||||
_pipeline.Initialize();
|
||||
|
||||
_samplerLinear = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
_samplerNearest = gd.CreateSampler(GAL.SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
||||
_samplerLinear = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Linear, MagFilter.Linear));
|
||||
_samplerNearest = gd.CreateSampler(SamplerCreateInfo.Create(MinFilter.Nearest, MagFilter.Nearest));
|
||||
|
||||
var blitResourceLayout = new ResourceLayoutBuilder()
|
||||
.Add(ResourceStages.Vertex, ResourceType.UniformBuffer, 1)
|
||||
@@ -416,7 +422,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
||||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||
|
||||
var rect = new Rectangle<float>(
|
||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||
@@ -424,7 +430,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@@ -440,7 +446,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (dstIsDepthOrStencil)
|
||||
{
|
||||
_pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit);
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always));
|
||||
}
|
||||
else if (src.Info.Target.IsMultisample())
|
||||
{
|
||||
@@ -465,12 +471,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.Draw(4, 1, 0, 0);
|
||||
|
||||
if (dstIsDepthOrStencil)
|
||||
{
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||
}
|
||||
|
||||
_pipeline.Finish(gd, cbs);
|
||||
@@ -517,7 +523,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
||||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||
|
||||
var rect = new Rectangle<float>(
|
||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||
@@ -525,7 +531,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@@ -541,7 +547,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat);
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
|
||||
var aspectFlags = src.Info.Format.ConvertAspectFlags();
|
||||
|
||||
@@ -606,7 +612,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (isDepth)
|
||||
{
|
||||
_pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit);
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -618,7 +624,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (isDepth)
|
||||
{
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -630,17 +636,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
return new StencilTestDescriptor(
|
||||
enabled,
|
||||
GAL.CompareOp.Always,
|
||||
GAL.StencilOp.Replace,
|
||||
GAL.StencilOp.Replace,
|
||||
GAL.StencilOp.Replace,
|
||||
CompareOp.Always,
|
||||
StencilOp.Replace,
|
||||
StencilOp.Replace,
|
||||
StencilOp.Replace,
|
||||
0,
|
||||
0xff,
|
||||
0xff,
|
||||
GAL.CompareOp.Always,
|
||||
GAL.StencilOp.Replace,
|
||||
GAL.StencilOp.Replace,
|
||||
GAL.StencilOp.Replace,
|
||||
CompareOp.Always,
|
||||
StencilOp.Replace,
|
||||
StencilOp.Replace,
|
||||
StencilOp.Replace,
|
||||
0,
|
||||
0xff,
|
||||
0xff);
|
||||
@@ -667,13 +673,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ClearColorBufferSize);
|
||||
|
||||
gd.BufferManager.SetData<float>(bufferHandle, 0, clearColor);
|
||||
gd.BufferManager.SetData(bufferHandle, 0, clearColor);
|
||||
|
||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, ClearColorBufferSize)) });
|
||||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
new Rectangle<float>(0, 0, dstWidth, dstHeight),
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@@ -703,10 +709,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetProgram(program);
|
||||
_pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat);
|
||||
_pipeline.SetRenderTargetColorMasks(new uint[] { componentMask });
|
||||
_pipeline.SetRenderTargetColorMasks(new[] { componentMask });
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.Draw(4, 1, 0, 0);
|
||||
_pipeline.Finish();
|
||||
|
||||
@@ -748,7 +754,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
|
||||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||
|
||||
var rect = new Rectangle<float>(
|
||||
MathF.Min(dstRegion.X1, dstRegion.X2),
|
||||
@@ -756,7 +762,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MathF.Abs(dstRegion.X2 - dstRegion.X1),
|
||||
MathF.Abs(dstRegion.Y2 - dstRegion.Y1));
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@@ -769,13 +775,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
pipeline.SetProgram(_programColorBlit);
|
||||
pipeline.SetViewports(viewports, false);
|
||||
pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
pipeline.Draw(4, 1, 0, 0);
|
||||
|
||||
gd.BufferManager.Delete(bufferHandle);
|
||||
}
|
||||
|
||||
public unsafe void ConvertI8ToI16(VulkanRenderer gd, CommandBufferScoped cbs, BufferHolder src, BufferHolder dst, int srcOffset, int size)
|
||||
public void ConvertI8ToI16(VulkanRenderer gd, CommandBufferScoped cbs, BufferHolder src, BufferHolder dst, int srcOffset, int size)
|
||||
{
|
||||
ChangeStride(gd, cbs, src, dst, srcOffset, size, 1, 2);
|
||||
}
|
||||
@@ -1093,11 +1099,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
// We can't use compute for this case because compute can't modify depth textures.
|
||||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||
|
||||
var rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@@ -1112,7 +1118,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
|
||||
for (int z = 0; z < depth; z++)
|
||||
{
|
||||
@@ -1120,7 +1126,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||
|
||||
_pipeline.SetRenderTarget(
|
||||
((TextureView)dstView).GetImageViewForAttachment(),
|
||||
dstView.GetImageViewForAttachment(),
|
||||
(uint)dst.Width,
|
||||
(uint)dst.Height,
|
||||
true,
|
||||
@@ -1225,11 +1231,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetCommandBuffer(cbs);
|
||||
|
||||
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
|
||||
Span<Viewport> viewports = stackalloc Viewport[1];
|
||||
|
||||
var rect = new Rectangle<float>(0, 0, dst.Width, dst.Height);
|
||||
|
||||
viewports[0] = new GAL.Viewport(
|
||||
viewports[0] = new Viewport(
|
||||
rect,
|
||||
ViewportSwizzle.PositiveX,
|
||||
ViewportSwizzle.PositiveY,
|
||||
@@ -1245,7 +1251,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_pipeline.SetRenderTargetColorMasks(new uint[] { 0xf });
|
||||
_pipeline.SetScissors(scissors);
|
||||
_pipeline.SetViewports(viewports, false);
|
||||
_pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip);
|
||||
_pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||
|
||||
_pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
|
||||
|
||||
@@ -1257,7 +1263,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var dstView = Create2DLayerView(dst, dstLayer + z, 0);
|
||||
|
||||
_pipeline.SetRenderTarget(
|
||||
((TextureView)dstView).GetImageViewForAttachment(),
|
||||
dstView.GetImageViewForAttachment(),
|
||||
(uint)dst.Width,
|
||||
(uint)dst.Height,
|
||||
(uint)samples,
|
||||
@@ -1291,7 +1297,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Fragment, 0, srcView, null);
|
||||
_pipeline.SetRenderTarget(
|
||||
((TextureView)dstView).GetView(format).GetImageViewForAttachment(),
|
||||
dstView.GetView(format).GetImageViewForAttachment(),
|
||||
(uint)dst.Width,
|
||||
(uint)dst.Height,
|
||||
(uint)samples,
|
||||
@@ -1365,7 +1371,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (isDepth)
|
||||
{
|
||||
_pipeline.SetProgram(fromMS ? _programDepthDrawToNonMs : _programDepthDrawToMs);
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1377,7 +1383,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (isDepth)
|
||||
{
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, GAL.CompareOp.Always));
|
||||
_pipeline.SetDepthTest(new DepthTestDescriptor(false, false, CompareOp.Always));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1420,7 +1426,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return (samplesInXLog2, samplesInYLog2);
|
||||
}
|
||||
|
||||
private static TextureView Create2DLayerView(TextureView from, int layer, int level, GAL.Format? format = null)
|
||||
private static TextureView Create2DLayerView(TextureView from, int layer, int level, Format? format = null)
|
||||
{
|
||||
if (from.Info.Target == Target.Texture2D && level == 0 && (format == null || format.Value == from.Info.Format))
|
||||
{
|
||||
@@ -1431,7 +1437,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
Target.Texture1DArray => Target.Texture1D,
|
||||
Target.Texture2DMultisampleArray => Target.Texture2DMultisample,
|
||||
_ => Target.Texture2D
|
||||
_ => Target.Texture2D,
|
||||
};
|
||||
|
||||
var info = new TextureCreateInfo(
|
||||
@@ -1454,55 +1460,55 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return from.CreateViewImpl(info, layer, level);
|
||||
}
|
||||
|
||||
private static GAL.Format GetFormat(int bytesPerPixel)
|
||||
private static Format GetFormat(int bytesPerPixel)
|
||||
{
|
||||
return bytesPerPixel switch
|
||||
{
|
||||
1 => GAL.Format.R8Uint,
|
||||
2 => GAL.Format.R16Uint,
|
||||
4 => GAL.Format.R32Uint,
|
||||
8 => GAL.Format.R32G32Uint,
|
||||
16 => GAL.Format.R32G32B32A32Uint,
|
||||
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}.")
|
||||
1 => Format.R8Uint,
|
||||
2 => Format.R16Uint,
|
||||
4 => Format.R32Uint,
|
||||
8 => Format.R32G32Uint,
|
||||
16 => Format.R32G32B32A32Uint,
|
||||
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}."),
|
||||
};
|
||||
}
|
||||
|
||||
private static GAL.Format GetFormat(int componentSize, int componentsCount)
|
||||
private static Format GetFormat(int componentSize, int componentsCount)
|
||||
{
|
||||
if (componentSize == 1)
|
||||
{
|
||||
return componentsCount switch
|
||||
{
|
||||
1 => GAL.Format.R8Uint,
|
||||
2 => GAL.Format.R8G8Uint,
|
||||
4 => GAL.Format.R8G8B8A8Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
||||
1 => Format.R8Uint,
|
||||
2 => Format.R8G8Uint,
|
||||
4 => Format.R8G8B8A8Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||
};
|
||||
}
|
||||
else if (componentSize == 2)
|
||||
|
||||
if (componentSize == 2)
|
||||
{
|
||||
return componentsCount switch
|
||||
{
|
||||
1 => GAL.Format.R16Uint,
|
||||
2 => GAL.Format.R16G16Uint,
|
||||
4 => GAL.Format.R16G16B16A16Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
||||
1 => Format.R16Uint,
|
||||
2 => Format.R16G16Uint,
|
||||
4 => Format.R16G16B16A16Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||
};
|
||||
}
|
||||
else if (componentSize == 4)
|
||||
|
||||
if (componentSize == 4)
|
||||
{
|
||||
return componentsCount switch
|
||||
{
|
||||
1 => GAL.Format.R32Uint,
|
||||
2 => GAL.Format.R32G32Uint,
|
||||
4 => GAL.Format.R32G32B32A32Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}.")
|
||||
1 => Format.R32Uint,
|
||||
2 => Format.R32G32Uint,
|
||||
4 => Format.R32G32B32A32Uint,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException($"Invalid component size {componentSize}.");
|
||||
}
|
||||
|
||||
throw new ArgumentException($"Invalid component size {componentSize}.");
|
||||
}
|
||||
|
||||
public void ConvertIndexBufferIndirect(
|
||||
@@ -1524,7 +1530,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
// TODO: Support conversion with primitive restart enabled.
|
||||
|
||||
BufferRange drawCountBufferAligned = new BufferRange(
|
||||
BufferRange drawCountBufferAligned = new(
|
||||
drawCountBuffer.Handle,
|
||||
drawCountBuffer.Offset & ~(UniformBufferAlignment - 1),
|
||||
UniformBufferAlignment);
|
||||
@@ -1562,7 +1568,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
shaderParams[22] = indirectDataStride / 4;
|
||||
shaderParams[23] = srcIndirectBufferOffset / 4;
|
||||
|
||||
pattern.OffsetIndex.CopyTo(shaderParams.Slice(0, pattern.OffsetIndex.Length));
|
||||
pattern.OffsetIndex.CopyTo(shaderParams[..pattern.OffsetIndex.Length]);
|
||||
|
||||
var patternBufferHandle = gd.BufferManager.CreateWithHandle(gd, ParamsBufferSize, out var patternBuffer);
|
||||
var patternBufferAuto = patternBuffer.GetBuffer();
|
||||
|
@@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal class HostMemoryAllocator
|
||||
{
|
||||
private struct HostMemoryAllocation
|
||||
private readonly struct HostMemoryAllocation
|
||||
{
|
||||
public readonly Auto<MemoryAllocation> Allocation;
|
||||
public readonly IntPtr Pointer;
|
||||
@@ -33,8 +33,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Device _device;
|
||||
private readonly object _lock = new();
|
||||
|
||||
private List<HostMemoryAllocation> _allocations;
|
||||
private IntervalTree<ulong, HostMemoryAllocation> _allocationTree;
|
||||
private readonly List<HostMemoryAllocation> _allocations;
|
||||
private readonly IntervalTree<ulong, HostMemoryAllocation> _allocationTree;
|
||||
|
||||
public HostMemoryAllocator(MemoryAllocator allocator, Vk api, ExtExternalMemoryHost hostMemoryApi, Device device)
|
||||
{
|
||||
@@ -100,19 +100,19 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return false;
|
||||
}
|
||||
|
||||
ImportMemoryHostPointerInfoEXT importInfo = new ImportMemoryHostPointerInfoEXT()
|
||||
ImportMemoryHostPointerInfoEXT importInfo = new()
|
||||
{
|
||||
SType = StructureType.ImportMemoryHostPointerInfoExt,
|
||||
HandleType = ExternalMemoryHandleTypeFlags.HostAllocationBitExt,
|
||||
PHostPointer = (void*)pageAlignedPointer
|
||||
PHostPointer = (void*)pageAlignedPointer,
|
||||
};
|
||||
|
||||
var memoryAllocateInfo = new MemoryAllocateInfo()
|
||||
var memoryAllocateInfo = new MemoryAllocateInfo
|
||||
{
|
||||
SType = StructureType.MemoryAllocateInfo,
|
||||
AllocationSize = pageAlignedSize,
|
||||
MemoryTypeIndex = (uint)memoryTypeIndex,
|
||||
PNext = &importInfo
|
||||
PNext = &importInfo,
|
||||
};
|
||||
|
||||
Result result = _api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory);
|
||||
|
@@ -85,11 +85,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
value = _list[id];
|
||||
return value != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
value = null;
|
||||
return false;
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
@@ -120,4 +118,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public int IndexStride { get; }
|
||||
public bool RepeatStart { get; }
|
||||
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
private int _currentSize;
|
||||
private BufferHandle _repeatingBuffer;
|
||||
|
||||
|
@@ -1,19 +1,20 @@
|
||||
using Silk.NET.Vulkan;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using IndexType = Silk.NET.Vulkan.IndexType;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal struct IndexBufferState
|
||||
{
|
||||
public static IndexBufferState Null => new IndexBufferState(GAL.BufferHandle.Null, 0, 0);
|
||||
public static IndexBufferState Null => new(BufferHandle.Null, 0, 0);
|
||||
|
||||
private readonly int _offset;
|
||||
private readonly int _size;
|
||||
private readonly IndexType _type;
|
||||
|
||||
private readonly GAL.BufferHandle _handle;
|
||||
private readonly BufferHandle _handle;
|
||||
private Auto<DisposableBuffer> _buffer;
|
||||
|
||||
public IndexBufferState(GAL.BufferHandle handle, int offset, int size, IndexType type)
|
||||
public IndexBufferState(BufferHandle handle, int offset, int size, IndexType type)
|
||||
{
|
||||
_handle = handle;
|
||||
_offset = offset;
|
||||
@@ -22,7 +23,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_buffer = null;
|
||||
}
|
||||
|
||||
public IndexBufferState(GAL.BufferHandle handle, int offset, int size)
|
||||
public IndexBufferState(BufferHandle handle, int offset, int size)
|
||||
{
|
||||
_handle = handle;
|
||||
_offset = offset;
|
||||
@@ -97,8 +98,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public Auto<DisposableBuffer> BindConvertedIndexBufferIndirect(
|
||||
VulkanRenderer gd,
|
||||
CommandBufferScoped cbs,
|
||||
GAL.BufferRange indirectBuffer,
|
||||
GAL.BufferRange drawCountBuffer,
|
||||
BufferRange indirectBuffer,
|
||||
BufferRange drawCountBuffer,
|
||||
IndexBufferPattern pattern,
|
||||
bool hasDrawCount,
|
||||
int maxDrawCount,
|
||||
@@ -110,7 +111,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
(var indexBufferAuto, var indirectBufferAuto) = gd.BufferManager.GetBufferTopologyConversionIndirect(
|
||||
gd,
|
||||
cbs,
|
||||
new GAL.BufferRange(_handle, _offset, _size),
|
||||
new BufferRange(_handle, _offset, _size),
|
||||
indirectBuffer,
|
||||
drawCountBuffer,
|
||||
pattern,
|
||||
@@ -132,7 +133,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return indirectBufferAuto;
|
||||
}
|
||||
|
||||
private int GetIndexSize()
|
||||
private readonly int GetIndexSize()
|
||||
{
|
||||
return _type switch
|
||||
{
|
||||
@@ -142,7 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
};
|
||||
}
|
||||
|
||||
public bool BoundEquals(Auto<DisposableBuffer> buffer)
|
||||
public readonly bool BoundEquals(Auto<DisposableBuffer> buffer)
|
||||
{
|
||||
return _buffer == buffer;
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly HostMemoryAllocator _hostMemory;
|
||||
|
||||
public DeviceMemory Memory { get; }
|
||||
public IntPtr HostPointer { get;}
|
||||
public IntPtr HostPointer { get; }
|
||||
public ulong Offset { get; }
|
||||
public ulong Size { get; }
|
||||
|
||||
|
@@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
class MemoryAllocator : IDisposable
|
||||
{
|
||||
private ulong MaxDeviceMemoryUsageEstimate = 16UL * 1024 * 1024 * 1024;
|
||||
private const ulong MaxDeviceMemoryUsageEstimate = 16UL * 1024 * 1024 * 1024;
|
||||
|
||||
private readonly Vk _api;
|
||||
private readonly VulkanPhysicalDevice _physicalDevice;
|
||||
@@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_physicalDevice = physicalDevice;
|
||||
_device = device;
|
||||
_blockLists = new List<MemoryAllocatorBlockList>();
|
||||
_blockAlignment = (int)Math.Min(int.MaxValue, MaxDeviceMemoryUsageEstimate / (ulong)_physicalDevice.PhysicalDeviceProperties.Limits.MaxMemoryAllocationCount);
|
||||
_blockAlignment = (int)Math.Min(int.MaxValue, MaxDeviceMemoryUsageEstimate / _physicalDevice.PhysicalDeviceProperties.Limits.MaxMemoryAllocationCount);
|
||||
}
|
||||
|
||||
public MemoryAllocation AllocateDeviceMemory(
|
||||
|
@@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Size = size;
|
||||
_freeRanges = new List<Range>
|
||||
{
|
||||
new Range(0, size)
|
||||
new Range(0, size),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
var range = _freeRanges[i];
|
||||
|
||||
ulong alignedOffset = BitUtils.AlignUp<ulong>(range.Offset, alignment);
|
||||
ulong alignedOffset = BitUtils.AlignUp(range.Offset, alignment);
|
||||
ulong sizeDelta = alignedOffset - range.Offset;
|
||||
ulong usableSize = range.Size - sizeDelta;
|
||||
|
||||
@@ -198,13 +198,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
ulong blockAlignedSize = BitUtils.AlignUp<ulong>(size, (ulong)_blockAlignment);
|
||||
ulong blockAlignedSize = BitUtils.AlignUp(size, (ulong)_blockAlignment);
|
||||
|
||||
var memoryAllocateInfo = new MemoryAllocateInfo()
|
||||
var memoryAllocateInfo = new MemoryAllocateInfo
|
||||
{
|
||||
SType = StructureType.MemoryAllocateInfo,
|
||||
AllocationSize = blockAlignedSize,
|
||||
MemoryTypeIndex = (uint)MemoryTypeIndex
|
||||
MemoryTypeIndex = (uint)MemoryTypeIndex,
|
||||
};
|
||||
|
||||
_api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory).ThrowOnError();
|
||||
@@ -213,12 +213,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (map)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
void* pointer = null;
|
||||
_api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError();
|
||||
hostPointer = (IntPtr)pointer;
|
||||
}
|
||||
void* pointer = null;
|
||||
_api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError();
|
||||
hostPointer = (IntPtr)pointer;
|
||||
}
|
||||
|
||||
var newBlock = new Block(deviceMemory, hostPointer, blockAlignedSize);
|
||||
@@ -238,10 +235,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
return (IntPtr)((nuint)(nint)block.HostPointer + offset);
|
||||
return (IntPtr)((nuint)block.HostPointer + offset);
|
||||
}
|
||||
|
||||
public unsafe void Free(Block block, ulong offset, ulong size)
|
||||
public void Free(Block block, ulong offset, ulong size)
|
||||
{
|
||||
block.Free(offset, size);
|
||||
|
||||
@@ -271,7 +268,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_blocks.Insert(index, block);
|
||||
}
|
||||
|
||||
public unsafe void Dispose()
|
||||
public void Dispose()
|
||||
{
|
||||
for (int i = 0; i < _blocks.Count; i++)
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
Error = 1,
|
||||
Warning = 2,
|
||||
Info = 3,
|
||||
Debug = 4
|
||||
Debug = 4,
|
||||
}
|
||||
|
||||
enum MVKConfigTraceVulkanCalls
|
||||
@@ -17,14 +17,14 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
None = 0,
|
||||
Enter = 1,
|
||||
EnterExit = 2,
|
||||
Duration = 3
|
||||
Duration = 3,
|
||||
}
|
||||
|
||||
enum MVKConfigAutoGPUCaptureScope
|
||||
{
|
||||
None = 0,
|
||||
Device = 1,
|
||||
Frame = 2
|
||||
Frame = 2,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
All = 0x00000001,
|
||||
MoltenVK = 0x00000002,
|
||||
WSI = 0x00000004,
|
||||
Portability = 0x00000008
|
||||
Portability = 0x00000008,
|
||||
}
|
||||
|
||||
enum MVKVkSemaphoreSupportStyle
|
||||
@@ -42,7 +42,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS_WHERE_SAFE = 1,
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_METAL_EVENTS = 2,
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_CALLBACK = 3,
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_MAX_ENUM = 0x7FFFFFFF
|
||||
MVK_CONFIG_VK_SEMAPHORE_SUPPORT_STYLE_MAX_ENUM = 0x7FFFFFFF,
|
||||
}
|
||||
|
||||
readonly struct Bool32
|
||||
@@ -60,7 +60,7 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
}
|
||||
|
||||
public static implicit operator bool(Bool32 val) => val.Value == 1;
|
||||
public static implicit operator Bool32(bool val) => new Bool32(val);
|
||||
public static implicit operator Bool32(bool val) => new(val);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
|
@@ -30,4 +30,4 @@ namespace Ryujinx.Graphics.Vulkan.MoltenVK
|
||||
vkSetMoltenVKConfigurationMVK(IntPtr.Zero, config, configSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,10 +8,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
/// </summary>
|
||||
class MultiFenceHolder
|
||||
{
|
||||
private static int BufferUsageTrackingGranularity = 4096;
|
||||
private static readonly int _bufferUsageTrackingGranularity = 4096;
|
||||
|
||||
private readonly FenceHolder[] _fences;
|
||||
private BufferUsageBitmap _bufferUsageBitmap;
|
||||
private readonly BufferUsageBitmap _bufferUsageBitmap;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the multiple fence holder.
|
||||
@@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public MultiFenceHolder(int size)
|
||||
{
|
||||
_fences = new FenceHolder[CommandBufferPool.MaxCommandBuffers];
|
||||
_bufferUsageBitmap = new BufferUsageBitmap(size, BufferUsageTrackingGranularity);
|
||||
_bufferUsageBitmap = new BufferUsageBitmap(size, _bufferUsageTrackingGranularity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -189,11 +189,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (hasTimeout)
|
||||
{
|
||||
signaled = FenceHelper.AllSignaled(api, device, fences.Slice(0, fenceCount), timeout);
|
||||
signaled = FenceHelper.AllSignaled(api, device, fences[..fenceCount], timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
FenceHelper.WaitAllIndefinitely(api, device, fences.Slice(0, fenceCount));
|
||||
FenceHelper.WaitAllIndefinitely(api, device, fences[..fenceCount]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < fenceCount; i++)
|
||||
|
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal class PersistentFlushBuffer : IDisposable
|
||||
{
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
|
||||
private BufferHolder _flushStorage;
|
||||
|
||||
@@ -19,10 +20,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (flushStorage == null || size > _flushStorage.Size)
|
||||
{
|
||||
if (flushStorage != null)
|
||||
{
|
||||
flushStorage.Dispose();
|
||||
}
|
||||
flushStorage?.Dispose();
|
||||
|
||||
flushStorage = _gd.BufferManager.Create(_gd, size);
|
||||
_flushStorage = flushStorage;
|
||||
@@ -59,7 +57,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public Span<byte> GetTextureData(CommandBufferPool cbp, TextureView view, int size)
|
||||
{
|
||||
GAL.TextureCreateInfo info = view.Info;
|
||||
TextureCreateInfo info = view.Info;
|
||||
|
||||
var flushStorage = ResizeIfNeeded(size);
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
@@ -7,6 +6,13 @@ using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using FrontFace = Ryujinx.Graphics.GAL.FrontFace;
|
||||
using IndexType = Ryujinx.Graphics.GAL.IndexType;
|
||||
using PolygonMode = Ryujinx.Graphics.GAL.PolygonMode;
|
||||
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
|
||||
using Viewport = Ryujinx.Graphics.GAL.Viewport;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@@ -28,7 +34,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
protected PipelineDynamicState DynamicState;
|
||||
private PipelineState _newState;
|
||||
private bool _stateDirty;
|
||||
private GAL.PrimitiveTopology _topology;
|
||||
private PrimitiveTopology _topology;
|
||||
|
||||
private ulong _currentPipelineHandle;
|
||||
|
||||
@@ -44,7 +50,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private ShaderCollection _program;
|
||||
|
||||
private Vector4<float>[] _renderScale = new Vector4<float>[73];
|
||||
private readonly Vector4<float>[] _renderScale = new Vector4<float>[73];
|
||||
private int _fragmentScaleCount;
|
||||
|
||||
protected FramebufferParams FramebufferParams;
|
||||
@@ -78,7 +84,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private bool _tfEnabled;
|
||||
private bool _tfActive;
|
||||
|
||||
private PipelineColorBlendAttachmentState[] _storedBlend;
|
||||
private readonly PipelineColorBlendAttachmentState[] _storedBlend;
|
||||
|
||||
private ulong _drawCountSinceBarrier;
|
||||
public ulong DrawCount { get; private set; }
|
||||
@@ -91,9 +97,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
AutoFlush = new AutoFlushCounter(gd);
|
||||
|
||||
var pipelineCacheCreateInfo = new PipelineCacheCreateInfo()
|
||||
var pipelineCacheCreateInfo = new PipelineCacheCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineCacheCreateInfo
|
||||
SType = StructureType.PipelineCacheCreateInfo,
|
||||
};
|
||||
|
||||
gd.Api.CreatePipelineCache(device, pipelineCacheCreateInfo, null, out PipelineCache).ThrowOnError();
|
||||
@@ -108,7 +114,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
using var emptyVb = gd.BufferManager.Create(gd, EmptyVbSize);
|
||||
emptyVb.SetData(0, new byte[EmptyVbSize]);
|
||||
_vertexBuffers[0] = new VertexBufferState(emptyVb.GetBuffer(), 0, 0, EmptyVbSize, 0);
|
||||
_vertexBuffers[0] = new VertexBufferState(emptyVb.GetBuffer(), 0, 0, EmptyVbSize);
|
||||
_vertexBuffersDirty = ulong.MaxValue >> (64 - _vertexBuffers.Length);
|
||||
|
||||
ClearScissor = new Rectangle<int>(0, 0, 0xffff, 0xffff);
|
||||
@@ -146,11 +152,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
};
|
||||
|
||||
Gd.Api.CmdPipelineBarrier(
|
||||
@@ -168,11 +174,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void ComputeBarrier()
|
||||
{
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
};
|
||||
|
||||
Gd.Api.CmdPipelineBarrier(
|
||||
@@ -188,7 +194,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ReadOnlySpan<ImageMemoryBarrier>.Empty);
|
||||
}
|
||||
|
||||
public void BeginTransformFeedback(GAL.PrimitiveTopology topology)
|
||||
public void BeginTransformFeedback(PrimitiveTopology topology)
|
||||
{
|
||||
_tfEnabled = true;
|
||||
}
|
||||
@@ -281,11 +287,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public unsafe void CommandBufferBarrier()
|
||||
{
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = BufferHolder.DefaultAccessFlags,
|
||||
DstAccessMask = AccessFlags.IndirectCommandReadBit
|
||||
DstAccessMask = AccessFlags.IndirectCommandReadBit,
|
||||
};
|
||||
|
||||
Gd.Api.CmdPipelineBarrier(
|
||||
@@ -374,10 +380,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
IndexBufferPattern pattern = _topology switch
|
||||
{
|
||||
GAL.PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||
GAL.PrimitiveTopology.TriangleFan or
|
||||
GAL.PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}")
|
||||
PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||
PrimitiveTopology.TriangleFan or
|
||||
PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}"),
|
||||
};
|
||||
|
||||
BufferHandle handle = pattern.GetRepeatingBuffer(vertexCount, out int indexCount);
|
||||
@@ -406,10 +412,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
pattern = _topology switch
|
||||
{
|
||||
GAL.PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||
GAL.PrimitiveTopology.TriangleFan or
|
||||
GAL.PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}")
|
||||
PrimitiveTopology.Quads => QuadsToTrisPattern,
|
||||
PrimitiveTopology.TriangleFan or
|
||||
PrimitiveTopology.Polygon => TriFanToTrisPattern,
|
||||
_ => throw new NotSupportedException($"Unsupported topology: {_topology}"),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -718,7 +724,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return CommandBuffer.Handle == cb.Handle;
|
||||
}
|
||||
|
||||
public void SetAlphaTest(bool enable, float reference, GAL.CompareOp op)
|
||||
public void SetAlphaTest(bool enable, float reference, CompareOp op)
|
||||
{
|
||||
// This is currently handled using shader specialization, as Vulkan does not support alpha test.
|
||||
// In the future, we may want to use this to write the reference value into the support buffer,
|
||||
@@ -847,13 +853,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SignalStateChange();
|
||||
}
|
||||
|
||||
public void SetFrontFace(GAL.FrontFace frontFace)
|
||||
public void SetFrontFace(FrontFace frontFace)
|
||||
{
|
||||
_newState.FrontFace = frontFace.Convert();
|
||||
SignalStateChange();
|
||||
}
|
||||
|
||||
public void SetImage(int binding, ITexture image, GAL.Format imageFormat)
|
||||
public void SetImage(int binding, ITexture image, Format imageFormat)
|
||||
{
|
||||
_descriptorSetUpdater.SetImage(binding, image, imageFormat);
|
||||
}
|
||||
@@ -863,7 +869,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_descriptorSetUpdater.SetImage(binding, image);
|
||||
}
|
||||
|
||||
public void SetIndexBuffer(BufferRange buffer, GAL.IndexType type)
|
||||
public void SetIndexBuffer(BufferRange buffer, IndexType type)
|
||||
{
|
||||
if (buffer.Handle != BufferHandle.Null)
|
||||
{
|
||||
@@ -897,12 +903,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SignalStateChange();
|
||||
}
|
||||
|
||||
public void SetOrigin(Origin origin)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
|
||||
public unsafe void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
||||
public void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
||||
{
|
||||
_newState.PatchControlPoints = (uint)vertices;
|
||||
SignalStateChange();
|
||||
@@ -910,15 +911,17 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// TODO: Default levels (likely needs emulation on shaders?)
|
||||
}
|
||||
|
||||
#pragma warning disable CA1822 // Mark member as static
|
||||
public void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
|
||||
public void SetPolygonMode(GAL.PolygonMode frontMode, GAL.PolygonMode backMode)
|
||||
public void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
#pragma warning restore CA1822
|
||||
|
||||
public void SetPrimitiveRestart(bool enable, int index)
|
||||
{
|
||||
@@ -927,7 +930,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SignalStateChange();
|
||||
}
|
||||
|
||||
public void SetPrimitiveTopology(GAL.PrimitiveTopology topology)
|
||||
public void SetPrimitiveTopology(PrimitiveTopology topology)
|
||||
{
|
||||
_topology = topology;
|
||||
|
||||
@@ -950,7 +953,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_newState.PipelineLayout = internalProgram.PipelineLayout;
|
||||
_newState.StagesCount = (uint)stages.Length;
|
||||
|
||||
stages.CopyTo(_newState.Stages.AsSpan().Slice(0, stages.Length));
|
||||
stages.CopyTo(_newState.Stages.AsSpan()[..stages.Length]);
|
||||
|
||||
SignalStateChange();
|
||||
|
||||
@@ -1149,10 +1152,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_descriptorSetUpdater.SetUniformBuffers(CommandBuffer, buffers);
|
||||
}
|
||||
|
||||
#pragma warning disable CA1822 // Mark member as static
|
||||
public void SetUserClipDistance(int index, bool enableClip)
|
||||
{
|
||||
// TODO.
|
||||
}
|
||||
#pragma warning restore CA1822
|
||||
|
||||
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
||||
{
|
||||
@@ -1298,7 +1303,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SignalStateChange();
|
||||
}
|
||||
|
||||
public void SetViewports(ReadOnlySpan<GAL.Viewport> viewports, bool disableTransform)
|
||||
public void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform)
|
||||
{
|
||||
int maxViewports = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1;
|
||||
int count = Math.Min(maxViewports, viewports.Length);
|
||||
@@ -1332,7 +1337,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
X = scale * 2f / viewports[0].Region.Width,
|
||||
Y = scale * 2f / viewports[0].Region.Height,
|
||||
Z = 1,
|
||||
W = disableTransformF
|
||||
W = disableTransformF,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1361,11 +1366,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public unsafe void TextureBarrier()
|
||||
{
|
||||
MemoryBarrier memoryBarrier = new MemoryBarrier()
|
||||
MemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.MemoryBarrier,
|
||||
SrcAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit
|
||||
DstAccessMask = AccessFlags.MemoryReadBit | AccessFlags.MemoryWriteBit,
|
||||
};
|
||||
|
||||
Gd.Api.CmdPipelineBarrier(
|
||||
@@ -1433,7 +1438,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// Just try to remove duplicate attachments.
|
||||
// Save a copy of the array to rebind when mask changes.
|
||||
|
||||
void maskOut()
|
||||
void MaskOut()
|
||||
{
|
||||
if (!_framebufferUsingColorWriteMask)
|
||||
{
|
||||
@@ -1467,12 +1472,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (vkBlend.ColorWriteMask == 0)
|
||||
{
|
||||
colors[i] = null;
|
||||
maskOut();
|
||||
MaskOut();
|
||||
}
|
||||
else if (vkBlend2.ColorWriteMask == 0)
|
||||
{
|
||||
colors[j] = null;
|
||||
maskOut();
|
||||
MaskOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1505,9 +1510,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
AttachmentDescription[] attachmentDescs = null;
|
||||
|
||||
var subpass = new SubpassDescription()
|
||||
var subpass = new SubpassDescription
|
||||
{
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||
};
|
||||
|
||||
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
||||
@@ -1572,7 +1577,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||
{
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo()
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo
|
||||
{
|
||||
SType = StructureType.RenderPassCreateInfo,
|
||||
PAttachments = pAttachmentDescs,
|
||||
@@ -1580,7 +1585,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PSubpasses = &subpass,
|
||||
SubpassCount = 1,
|
||||
PDependencies = &subpassDependency,
|
||||
DependencyCount = 1
|
||||
DependencyCount = 1,
|
||||
};
|
||||
|
||||
Gd.Api.CreateRenderPass(Device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
||||
@@ -1688,14 +1693,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var renderArea = new Rect2D(null, new Extent2D(FramebufferParams.Width, FramebufferParams.Height));
|
||||
var clearValue = new ClearValue();
|
||||
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo()
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo
|
||||
{
|
||||
SType = StructureType.RenderPassBeginInfo,
|
||||
RenderPass = _renderPass.Get(Cbs).Value,
|
||||
Framebuffer = _framebuffer.Get(Cbs).Value,
|
||||
RenderArea = renderArea,
|
||||
PClearValues = &clearValue,
|
||||
ClearValueCount = 1
|
||||
ClearValueCount = 1,
|
||||
};
|
||||
|
||||
Gd.Api.CmdBeginRenderPass(CommandBuffer, renderPassBeginInfo, SubpassContents.Inline);
|
||||
|
@@ -2,6 +2,8 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using Format = Silk.NET.Vulkan.Format;
|
||||
using PolygonMode = Silk.NET.Vulkan.PolygonMode;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@@ -16,15 +18,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
AttachmentDescription[] attachmentDescs = null;
|
||||
|
||||
var subpass = new SubpassDescription()
|
||||
var subpass = new SubpassDescription
|
||||
{
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||
};
|
||||
|
||||
AttachmentReference* attachmentReferences = stackalloc AttachmentReference[MaxAttachments];
|
||||
|
||||
Span<int> attachmentIndices = stackalloc int[MaxAttachments];
|
||||
Span<Silk.NET.Vulkan.Format> attachmentFormats = stackalloc Silk.NET.Vulkan.Format[MaxAttachments];
|
||||
Span<Format> attachmentFormats = stackalloc Format[MaxAttachments];
|
||||
|
||||
int attachmentCount = 0;
|
||||
int colorCount = 0;
|
||||
@@ -106,7 +108,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (AttachmentDescription* pAttachmentDescs = attachmentDescs)
|
||||
{
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo()
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo
|
||||
{
|
||||
SType = StructureType.RenderPassCreateInfo,
|
||||
PAttachments = pAttachmentDescs,
|
||||
@@ -114,7 +116,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PSubpasses = &subpass,
|
||||
SubpassCount = 1,
|
||||
PDependencies = &subpassDependency,
|
||||
DependencyCount = 1
|
||||
DependencyCount = 1,
|
||||
};
|
||||
|
||||
gd.Api.CreateRenderPass(device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
||||
@@ -151,7 +153,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public static PipelineState ToVulkanPipelineState(this ProgramPipelineState state, VulkanRenderer gd)
|
||||
{
|
||||
PipelineState pipeline = new PipelineState();
|
||||
PipelineState pipeline = new();
|
||||
pipeline.Initialize();
|
||||
|
||||
// It is assumed that Dynamic State is enabled when this conversion is used.
|
||||
@@ -178,7 +180,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
pipeline.MaxDepthBounds = 0f; // Not implemented.
|
||||
|
||||
pipeline.PatchControlPoints = state.PatchControlPoints;
|
||||
pipeline.PolygonMode = Silk.NET.Vulkan.PolygonMode.Fill; // Not implemented.
|
||||
pipeline.PolygonMode = PolygonMode.Fill; // Not implemented.
|
||||
pipeline.PrimitiveRestartEnable = state.PrimitiveRestartEnable;
|
||||
pipeline.RasterizerDiscardEnable = state.RasterizerDiscard;
|
||||
pipeline.SamplesCount = (uint)state.SamplesCount;
|
||||
|
@@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Scissor = 1 << 2,
|
||||
Stencil = 1 << 3,
|
||||
Viewport = 1 << 4,
|
||||
All = Blend | DepthBias | Scissor | Stencil | Viewport
|
||||
All = Blend | DepthBias | Scissor | Stencil | Viewport,
|
||||
}
|
||||
|
||||
private DirtyFlags _dirty;
|
||||
@@ -139,7 +139,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan());
|
||||
}
|
||||
|
||||
private void RecordDepthBias(Vk api, CommandBuffer commandBuffer)
|
||||
private readonly void RecordDepthBias(Vk api, CommandBuffer commandBuffer)
|
||||
{
|
||||
api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);
|
||||
}
|
||||
@@ -149,7 +149,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
api.CmdSetScissor(commandBuffer, 0, (uint)ScissorsCount, _scissors.AsSpan());
|
||||
}
|
||||
|
||||
private void RecordStencilMasks(Vk api, CommandBuffer commandBuffer)
|
||||
private readonly void RecordStencilMasks(Vk api, CommandBuffer commandBuffer)
|
||||
{
|
||||
api.CmdSetStencilCompareMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backCompareMask);
|
||||
api.CmdSetStencilWriteMask(commandBuffer, StencilFaceFlags.FaceBackBit, _backWriteMask);
|
||||
|
@@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private ulong _byteWeight;
|
||||
|
||||
private List<BufferHolder> _backingSwaps;
|
||||
private readonly List<BufferHolder> _backingSwaps;
|
||||
|
||||
public PipelineFull(VulkanRenderer gd, Device device) : base(gd, device)
|
||||
{
|
||||
@@ -116,15 +116,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (Gd.Capabilities.SupportsConditionalRendering)
|
||||
{
|
||||
var buffer = evt.GetBuffer().Get(Cbs, 0, sizeof(long)).Value;
|
||||
var flags = isEqual ? ConditionalRenderingFlagsEXT.InvertedBitExt : 0;
|
||||
// var buffer = evt.GetBuffer().Get(Cbs, 0, sizeof(long)).Value;
|
||||
// var flags = isEqual ? ConditionalRenderingFlagsEXT.InvertedBitExt : 0;
|
||||
|
||||
var conditionalRenderingBeginInfo = new ConditionalRenderingBeginInfoEXT()
|
||||
{
|
||||
SType = StructureType.ConditionalRenderingBeginInfoExt,
|
||||
Buffer = buffer,
|
||||
Flags = flags
|
||||
};
|
||||
// var conditionalRenderingBeginInfo = new ConditionalRenderingBeginInfoEXT
|
||||
// {
|
||||
// SType = StructureType.ConditionalRenderingBeginInfoExt,
|
||||
// Buffer = buffer,
|
||||
// Flags = flags,
|
||||
// };
|
||||
|
||||
// Gd.ConditionalRenderingApi.CmdBeginConditionalRendering(CommandBuffer, conditionalRenderingBeginInfo);
|
||||
}
|
||||
@@ -156,10 +156,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public CommandBufferScoped GetPreloadCommandBuffer()
|
||||
{
|
||||
if (PreloadCbs == null)
|
||||
{
|
||||
PreloadCbs = Gd.CommandBufferPool.Rent();
|
||||
}
|
||||
PreloadCbs ??= Gd.CommandBufferPool.Rent();
|
||||
|
||||
return PreloadCbs.Value;
|
||||
}
|
||||
@@ -192,7 +189,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
CommandBufferScoped? cbs = null;
|
||||
|
||||
_backingSwaps.RemoveAll((holder) => holder.TryBackingSwap(ref cbs));
|
||||
_backingSwaps.RemoveAll(holder => holder.TryBackingSwap(ref cbs));
|
||||
|
||||
cbs?.Dispose();
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
HashCode hasher = new HashCode();
|
||||
HashCode hasher = new();
|
||||
|
||||
if (SetDescriptors != null)
|
||||
{
|
||||
@@ -83,10 +83,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
var key = new PlceKey(setDescriptors, usePushDescriptors);
|
||||
|
||||
return _plces.GetOrAdd(key, (newKey) => new PipelineLayoutCacheEntry(gd, device, setDescriptors, usePushDescriptors));
|
||||
return _plces.GetOrAdd(key, newKey => new PipelineLayoutCacheEntry(gd, device, setDescriptors, usePushDescriptors));
|
||||
}
|
||||
|
||||
protected virtual unsafe void Dispose(bool disposing)
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
|
@@ -45,23 +45,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
stages = activeStages;
|
||||
}
|
||||
|
||||
layoutBindings[descIndex] = new DescriptorSetLayoutBinding()
|
||||
layoutBindings[descIndex] = new DescriptorSetLayoutBinding
|
||||
{
|
||||
Binding = (uint)descriptor.Binding,
|
||||
DescriptorType = descriptor.Type.Convert(),
|
||||
DescriptorCount = (uint)descriptor.Count,
|
||||
StageFlags = stages.Convert()
|
||||
StageFlags = stages.Convert(),
|
||||
};
|
||||
}
|
||||
|
||||
fixed (DescriptorSetLayoutBinding* pLayoutBindings = layoutBindings)
|
||||
{
|
||||
var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
|
||||
var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
|
||||
{
|
||||
SType = StructureType.DescriptorSetLayoutCreateInfo,
|
||||
PBindings = pLayoutBindings,
|
||||
BindingCount = (uint)layoutBindings.Length,
|
||||
Flags = usePushDescriptors && setIndex == 0 ? DescriptorSetLayoutCreateFlags.PushDescriptorBitKhr : DescriptorSetLayoutCreateFlags.None
|
||||
Flags = usePushDescriptors && setIndex == 0 ? DescriptorSetLayoutCreateFlags.PushDescriptorBitKhr : DescriptorSetLayoutCreateFlags.None,
|
||||
};
|
||||
|
||||
gd.Api.CreateDescriptorSetLayout(device, descriptorSetLayoutCreateInfo, null, out layouts[setIndex]).ThrowOnError();
|
||||
@@ -72,11 +72,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (DescriptorSetLayout* pLayouts = layouts)
|
||||
{
|
||||
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
|
||||
var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineLayoutCreateInfo,
|
||||
PSetLayouts = pLayouts,
|
||||
SetLayoutCount = (uint)layouts.Length
|
||||
SetLayoutCount = (uint)layouts.Length,
|
||||
};
|
||||
|
||||
gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
|
||||
|
@@ -13,301 +13,301 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public float LineWidth
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id0 >> 0) & 0xFFFFFFFF));
|
||||
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id0 >> 0) & 0xFFFFFFFF));
|
||||
set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
||||
}
|
||||
|
||||
public float DepthBiasClamp
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id0 >> 32) & 0xFFFFFFFF));
|
||||
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id0 >> 32) & 0xFFFFFFFF));
|
||||
set => Internal.Id0 = (Internal.Id0 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||
}
|
||||
|
||||
public float DepthBiasConstantFactor
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id1 >> 0) & 0xFFFFFFFF));
|
||||
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id1 >> 0) & 0xFFFFFFFF));
|
||||
set => Internal.Id1 = (Internal.Id1 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
||||
}
|
||||
|
||||
public float DepthBiasSlopeFactor
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id1 >> 32) & 0xFFFFFFFF));
|
||||
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id1 >> 32) & 0xFFFFFFFF));
|
||||
set => Internal.Id1 = (Internal.Id1 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||
}
|
||||
|
||||
public uint StencilFrontCompareMask
|
||||
{
|
||||
get => (uint)((Internal.Id2 >> 0) & 0xFFFFFFFF);
|
||||
readonly get => (uint)((Internal.Id2 >> 0) & 0xFFFFFFFF);
|
||||
set => Internal.Id2 = (Internal.Id2 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint StencilFrontWriteMask
|
||||
{
|
||||
get => (uint)((Internal.Id2 >> 32) & 0xFFFFFFFF);
|
||||
readonly get => (uint)((Internal.Id2 >> 32) & 0xFFFFFFFF);
|
||||
set => Internal.Id2 = (Internal.Id2 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||
}
|
||||
|
||||
public uint StencilFrontReference
|
||||
{
|
||||
get => (uint)((Internal.Id3 >> 0) & 0xFFFFFFFF);
|
||||
readonly get => (uint)((Internal.Id3 >> 0) & 0xFFFFFFFF);
|
||||
set => Internal.Id3 = (Internal.Id3 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint StencilBackCompareMask
|
||||
{
|
||||
get => (uint)((Internal.Id3 >> 32) & 0xFFFFFFFF);
|
||||
readonly get => (uint)((Internal.Id3 >> 32) & 0xFFFFFFFF);
|
||||
set => Internal.Id3 = (Internal.Id3 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||
}
|
||||
|
||||
public uint StencilBackWriteMask
|
||||
{
|
||||
get => (uint)((Internal.Id4 >> 0) & 0xFFFFFFFF);
|
||||
readonly get => (uint)((Internal.Id4 >> 0) & 0xFFFFFFFF);
|
||||
set => Internal.Id4 = (Internal.Id4 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint StencilBackReference
|
||||
{
|
||||
get => (uint)((Internal.Id4 >> 32) & 0xFFFFFFFF);
|
||||
readonly get => (uint)((Internal.Id4 >> 32) & 0xFFFFFFFF);
|
||||
set => Internal.Id4 = (Internal.Id4 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||
}
|
||||
|
||||
public float MinDepthBounds
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id5 >> 0) & 0xFFFFFFFF));
|
||||
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id5 >> 0) & 0xFFFFFFFF));
|
||||
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF00000000) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 0);
|
||||
}
|
||||
|
||||
public float MaxDepthBounds
|
||||
{
|
||||
get => BitConverter.Int32BitsToSingle((int)((Internal.Id5 >> 32) & 0xFFFFFFFF));
|
||||
readonly get => BitConverter.Int32BitsToSingle((int)((Internal.Id5 >> 32) & 0xFFFFFFFF));
|
||||
set => Internal.Id5 = (Internal.Id5 & 0xFFFFFFFF) | ((ulong)(uint)BitConverter.SingleToInt32Bits(value) << 32);
|
||||
}
|
||||
|
||||
public PolygonMode PolygonMode
|
||||
{
|
||||
get => (PolygonMode)((Internal.Id6 >> 0) & 0x3FFFFFFF);
|
||||
readonly get => (PolygonMode)((Internal.Id6 >> 0) & 0x3FFFFFFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFFFC0000000) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint StagesCount
|
||||
{
|
||||
get => (byte)((Internal.Id6 >> 30) & 0xFF);
|
||||
readonly get => (byte)((Internal.Id6 >> 30) & 0xFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFFFC03FFFFFFF) | ((ulong)value << 30);
|
||||
}
|
||||
|
||||
public uint VertexAttributeDescriptionsCount
|
||||
{
|
||||
get => (byte)((Internal.Id6 >> 38) & 0xFF);
|
||||
readonly get => (byte)((Internal.Id6 >> 38) & 0xFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFFFC03FFFFFFFFF) | ((ulong)value << 38);
|
||||
}
|
||||
|
||||
public uint VertexBindingDescriptionsCount
|
||||
{
|
||||
get => (byte)((Internal.Id6 >> 46) & 0xFF);
|
||||
readonly get => (byte)((Internal.Id6 >> 46) & 0xFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xFFC03FFFFFFFFFFF) | ((ulong)value << 46);
|
||||
}
|
||||
|
||||
public uint ViewportsCount
|
||||
{
|
||||
get => (byte)((Internal.Id6 >> 54) & 0xFF);
|
||||
readonly get => (byte)((Internal.Id6 >> 54) & 0xFF);
|
||||
set => Internal.Id6 = (Internal.Id6 & 0xC03FFFFFFFFFFFFF) | ((ulong)value << 54);
|
||||
}
|
||||
|
||||
public uint ScissorsCount
|
||||
{
|
||||
get => (byte)((Internal.Id7 >> 0) & 0xFF);
|
||||
readonly get => (byte)((Internal.Id7 >> 0) & 0xFF);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFFFF00) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint ColorBlendAttachmentStateCount
|
||||
{
|
||||
get => (byte)((Internal.Id7 >> 8) & 0xFF);
|
||||
readonly get => (byte)((Internal.Id7 >> 8) & 0xFF);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFFF00FF) | ((ulong)value << 8);
|
||||
}
|
||||
|
||||
public PrimitiveTopology Topology
|
||||
{
|
||||
get => (PrimitiveTopology)((Internal.Id7 >> 16) & 0xF);
|
||||
readonly get => (PrimitiveTopology)((Internal.Id7 >> 16) & 0xF);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFFF0FFFF) | ((ulong)value << 16);
|
||||
}
|
||||
|
||||
public LogicOp LogicOp
|
||||
{
|
||||
get => (LogicOp)((Internal.Id7 >> 20) & 0xF);
|
||||
readonly get => (LogicOp)((Internal.Id7 >> 20) & 0xF);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFFF0FFFFF) | ((ulong)value << 20);
|
||||
}
|
||||
|
||||
public CompareOp DepthCompareOp
|
||||
{
|
||||
get => (CompareOp)((Internal.Id7 >> 24) & 0x7);
|
||||
readonly get => (CompareOp)((Internal.Id7 >> 24) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFF8FFFFFF) | ((ulong)value << 24);
|
||||
}
|
||||
|
||||
public StencilOp StencilFrontFailOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id7 >> 27) & 0x7);
|
||||
readonly get => (StencilOp)((Internal.Id7 >> 27) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFFC7FFFFFF) | ((ulong)value << 27);
|
||||
}
|
||||
|
||||
public StencilOp StencilFrontPassOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id7 >> 30) & 0x7);
|
||||
readonly get => (StencilOp)((Internal.Id7 >> 30) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFFE3FFFFFFF) | ((ulong)value << 30);
|
||||
}
|
||||
|
||||
public StencilOp StencilFrontDepthFailOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id7 >> 33) & 0x7);
|
||||
readonly get => (StencilOp)((Internal.Id7 >> 33) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFFF1FFFFFFFF) | ((ulong)value << 33);
|
||||
}
|
||||
|
||||
public CompareOp StencilFrontCompareOp
|
||||
{
|
||||
get => (CompareOp)((Internal.Id7 >> 36) & 0x7);
|
||||
readonly get => (CompareOp)((Internal.Id7 >> 36) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFF8FFFFFFFFF) | ((ulong)value << 36);
|
||||
}
|
||||
|
||||
public StencilOp StencilBackFailOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id7 >> 39) & 0x7);
|
||||
readonly get => (StencilOp)((Internal.Id7 >> 39) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFFC7FFFFFFFFF) | ((ulong)value << 39);
|
||||
}
|
||||
|
||||
public StencilOp StencilBackPassOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id7 >> 42) & 0x7);
|
||||
readonly get => (StencilOp)((Internal.Id7 >> 42) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFFE3FFFFFFFFFF) | ((ulong)value << 42);
|
||||
}
|
||||
|
||||
public StencilOp StencilBackDepthFailOp
|
||||
{
|
||||
get => (StencilOp)((Internal.Id7 >> 45) & 0x7);
|
||||
readonly get => (StencilOp)((Internal.Id7 >> 45) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFFF1FFFFFFFFFFF) | ((ulong)value << 45);
|
||||
}
|
||||
|
||||
public CompareOp StencilBackCompareOp
|
||||
{
|
||||
get => (CompareOp)((Internal.Id7 >> 48) & 0x7);
|
||||
readonly get => (CompareOp)((Internal.Id7 >> 48) & 0x7);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFF8FFFFFFFFFFFF) | ((ulong)value << 48);
|
||||
}
|
||||
|
||||
public CullModeFlags CullMode
|
||||
{
|
||||
get => (CullModeFlags)((Internal.Id7 >> 51) & 0x3);
|
||||
readonly get => (CullModeFlags)((Internal.Id7 >> 51) & 0x3);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFE7FFFFFFFFFFFF) | ((ulong)value << 51);
|
||||
}
|
||||
|
||||
public bool PrimitiveRestartEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 53) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 53) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFDFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 53);
|
||||
}
|
||||
|
||||
public bool DepthClampEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 54) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 54) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFFBFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 54);
|
||||
}
|
||||
|
||||
public bool RasterizerDiscardEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 55) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 55) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFF7FFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 55);
|
||||
}
|
||||
|
||||
public FrontFace FrontFace
|
||||
{
|
||||
get => (FrontFace)((Internal.Id7 >> 56) & 0x1);
|
||||
readonly get => (FrontFace)((Internal.Id7 >> 56) & 0x1);
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFEFFFFFFFFFFFFFF) | ((ulong)value << 56);
|
||||
}
|
||||
|
||||
public bool DepthBiasEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 57) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 57) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFDFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 57);
|
||||
}
|
||||
|
||||
public bool DepthTestEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 58) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 58) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xFBFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 58);
|
||||
}
|
||||
|
||||
public bool DepthWriteEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 59) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 59) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xF7FFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 59);
|
||||
}
|
||||
|
||||
public bool DepthBoundsTestEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 60) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 60) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xEFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 60);
|
||||
}
|
||||
|
||||
public bool StencilTestEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 61) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 61) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xDFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 61);
|
||||
}
|
||||
|
||||
public bool LogicOpEnable
|
||||
{
|
||||
get => ((Internal.Id7 >> 62) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 62) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0xBFFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 62);
|
||||
}
|
||||
|
||||
public bool HasDepthStencil
|
||||
{
|
||||
get => ((Internal.Id7 >> 63) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id7 >> 63) & 0x1) != 0UL;
|
||||
set => Internal.Id7 = (Internal.Id7 & 0x7FFFFFFFFFFFFFFF) | ((value ? 1UL : 0UL) << 63);
|
||||
}
|
||||
|
||||
public uint PatchControlPoints
|
||||
{
|
||||
get => (uint)((Internal.Id8 >> 0) & 0xFFFFFFFF);
|
||||
readonly get => (uint)((Internal.Id8 >> 0) & 0xFFFFFFFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF00000000) | ((ulong)value << 0);
|
||||
}
|
||||
|
||||
public uint SamplesCount
|
||||
{
|
||||
get => (uint)((Internal.Id8 >> 32) & 0xFFFFFFFF);
|
||||
readonly get => (uint)((Internal.Id8 >> 32) & 0xFFFFFFFF);
|
||||
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFF) | ((ulong)value << 32);
|
||||
}
|
||||
|
||||
public bool AlphaToCoverageEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 0) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id9 >> 0) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFE) | ((value ? 1UL : 0UL) << 0);
|
||||
}
|
||||
|
||||
public bool AlphaToOneEnable
|
||||
{
|
||||
get => ((Internal.Id9 >> 1) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id9 >> 1) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFD) | ((value ? 1UL : 0UL) << 1);
|
||||
}
|
||||
|
||||
public bool AdvancedBlendSrcPreMultiplied
|
||||
{
|
||||
get => ((Internal.Id9 >> 2) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id9 >> 2) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFFB) | ((value ? 1UL : 0UL) << 2);
|
||||
}
|
||||
|
||||
public bool AdvancedBlendDstPreMultiplied
|
||||
{
|
||||
get => ((Internal.Id9 >> 3) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id9 >> 3) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFF7) | ((value ? 1UL : 0UL) << 3);
|
||||
}
|
||||
|
||||
public BlendOverlapEXT AdvancedBlendOverlap
|
||||
{
|
||||
get => (BlendOverlapEXT)((Internal.Id9 >> 4) & 0x3);
|
||||
readonly get => (BlendOverlapEXT)((Internal.Id9 >> 4) & 0x3);
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFCF) | ((ulong)value << 4);
|
||||
}
|
||||
|
||||
public bool DepthMode
|
||||
{
|
||||
get => ((Internal.Id9 >> 6) & 0x1) != 0UL;
|
||||
readonly get => ((Internal.Id9 >> 6) & 0x1) != 0UL;
|
||||
set => Internal.Id9 = (Internal.Id9 & 0xFFFFFFFFFFFFFFBF) | ((value ? 1UL : 0UL) << 6);
|
||||
}
|
||||
|
||||
@@ -325,10 +325,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
for (int index = 0; index < Constants.MaxShaderStages; index++)
|
||||
{
|
||||
StageRequiredSubgroupSizes[index] = new PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT()
|
||||
StageRequiredSubgroupSizes[index] = new PipelineShaderStageRequiredSubgroupSizeCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.PipelineShaderStageRequiredSubgroupSizeCreateInfoExt,
|
||||
RequiredSubgroupSize = RequiredSubgroupSize
|
||||
RequiredSubgroupSize = RequiredSubgroupSize,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -357,12 +357,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
UpdateStageRequiredSubgroupSizes(gd, 1);
|
||||
}
|
||||
|
||||
var pipelineCreateInfo = new ComputePipelineCreateInfo()
|
||||
var pipelineCreateInfo = new ComputePipelineCreateInfo
|
||||
{
|
||||
SType = StructureType.ComputePipelineCreateInfo,
|
||||
Stage = Stages[0],
|
||||
BasePipelineIndex = -1,
|
||||
Layout = PipelineLayout
|
||||
Layout = PipelineLayout,
|
||||
};
|
||||
|
||||
Pipeline pipelineHandle = default;
|
||||
@@ -431,7 +431,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
VertexAttributeDescriptionCount = VertexAttributeDescriptionsCount,
|
||||
PVertexAttributeDescriptions = isMoltenVk ? pVertexAttributeDescriptions2 : pVertexAttributeDescriptions,
|
||||
VertexBindingDescriptionCount = VertexBindingDescriptionsCount,
|
||||
PVertexBindingDescriptions = pVertexBindingDescriptions
|
||||
PVertexBindingDescriptions = pVertexBindingDescriptions,
|
||||
};
|
||||
|
||||
bool primitiveRestartEnable = PrimitiveRestartEnable;
|
||||
@@ -453,20 +453,20 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
primitiveRestartEnable &= topologySupportsRestart;
|
||||
|
||||
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo()
|
||||
var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineInputAssemblyStateCreateInfo,
|
||||
PrimitiveRestartEnable = primitiveRestartEnable,
|
||||
Topology = Topology
|
||||
Topology = Topology,
|
||||
};
|
||||
|
||||
var tessellationState = new PipelineTessellationStateCreateInfo()
|
||||
var tessellationState = new PipelineTessellationStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineTessellationStateCreateInfo,
|
||||
PatchControlPoints = PatchControlPoints
|
||||
PatchControlPoints = PatchControlPoints,
|
||||
};
|
||||
|
||||
var rasterizationState = new PipelineRasterizationStateCreateInfo()
|
||||
var rasterizationState = new PipelineRasterizationStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineRasterizationStateCreateInfo,
|
||||
DepthClampEnable = DepthClampEnable,
|
||||
@@ -478,24 +478,24 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DepthBiasEnable = DepthBiasEnable,
|
||||
DepthBiasClamp = DepthBiasClamp,
|
||||
DepthBiasConstantFactor = DepthBiasConstantFactor,
|
||||
DepthBiasSlopeFactor = DepthBiasSlopeFactor
|
||||
DepthBiasSlopeFactor = DepthBiasSlopeFactor,
|
||||
};
|
||||
|
||||
var viewportState = new PipelineViewportStateCreateInfo()
|
||||
var viewportState = new PipelineViewportStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineViewportStateCreateInfo,
|
||||
ViewportCount = ViewportsCount,
|
||||
PViewports = pViewports,
|
||||
ScissorCount = ScissorsCount,
|
||||
PScissors = pScissors
|
||||
PScissors = pScissors,
|
||||
};
|
||||
|
||||
if (gd.Capabilities.SupportsDepthClipControl)
|
||||
{
|
||||
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT()
|
||||
var viewportDepthClipControlState = new PipelineViewportDepthClipControlCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.PipelineViewportDepthClipControlCreateInfoExt,
|
||||
NegativeOneToOne = DepthMode
|
||||
NegativeOneToOne = DepthMode,
|
||||
};
|
||||
|
||||
viewportState.PNext = &viewportDepthClipControlState;
|
||||
@@ -508,7 +508,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
RasterizationSamples = TextureStorage.ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, SamplesCount),
|
||||
MinSampleShading = 1,
|
||||
AlphaToCoverageEnable = AlphaToCoverageEnable,
|
||||
AlphaToOneEnable = AlphaToOneEnable
|
||||
AlphaToOneEnable = AlphaToOneEnable,
|
||||
};
|
||||
|
||||
var stencilFront = new StencilOpState(
|
||||
@@ -529,7 +529,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
StencilBackWriteMask,
|
||||
StencilBackReference);
|
||||
|
||||
var depthStencilState = new PipelineDepthStencilStateCreateInfo()
|
||||
var depthStencilState = new PipelineDepthStencilStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineDepthStencilStateCreateInfo,
|
||||
DepthTestEnable = DepthTestEnable,
|
||||
@@ -540,7 +540,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Front = stencilFront,
|
||||
Back = stencilBack,
|
||||
MinDepthBounds = MinDepthBounds,
|
||||
MaxDepthBounds = MaxDepthBounds
|
||||
MaxDepthBounds = MaxDepthBounds,
|
||||
};
|
||||
|
||||
uint blendEnables = 0;
|
||||
@@ -564,13 +564,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
var colorBlendState = new PipelineColorBlendStateCreateInfo()
|
||||
var colorBlendState = new PipelineColorBlendStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineColorBlendStateCreateInfo,
|
||||
LogicOpEnable = LogicOpEnable,
|
||||
LogicOp = LogicOp,
|
||||
AttachmentCount = ColorBlendAttachmentStateCount,
|
||||
PAttachments = pColorBlendAttachmentState
|
||||
PAttachments = pColorBlendAttachmentState,
|
||||
};
|
||||
|
||||
PipelineColorBlendAdvancedStateCreateInfoEXT colorBlendAdvancedState;
|
||||
@@ -579,12 +579,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
!AdvancedBlendDstPreMultiplied ||
|
||||
AdvancedBlendOverlap != BlendOverlapEXT.UncorrelatedExt)
|
||||
{
|
||||
colorBlendAdvancedState = new PipelineColorBlendAdvancedStateCreateInfoEXT()
|
||||
colorBlendAdvancedState = new PipelineColorBlendAdvancedStateCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.PipelineColorBlendAdvancedStateCreateInfoExt,
|
||||
SrcPremultiplied = AdvancedBlendSrcPreMultiplied,
|
||||
DstPremultiplied = AdvancedBlendDstPreMultiplied,
|
||||
BlendOverlap = AdvancedBlendOverlap
|
||||
BlendOverlap = AdvancedBlendOverlap,
|
||||
};
|
||||
|
||||
colorBlendState.PNext = &colorBlendAdvancedState;
|
||||
@@ -609,11 +609,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
dynamicStates[8] = DynamicState.VertexInputBindingStrideExt;
|
||||
}
|
||||
|
||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo()
|
||||
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineDynamicStateCreateInfo,
|
||||
DynamicStateCount = (uint)dynamicStatesCount,
|
||||
PDynamicStates = dynamicStates
|
||||
PDynamicStates = dynamicStates,
|
||||
};
|
||||
|
||||
if (gd.Capabilities.SupportsSubgroupSizeControl)
|
||||
@@ -621,7 +621,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
UpdateStageRequiredSubgroupSizes(gd, (int)StagesCount);
|
||||
}
|
||||
|
||||
var pipelineCreateInfo = new GraphicsPipelineCreateInfo()
|
||||
var pipelineCreateInfo = new GraphicsPipelineCreateInfo
|
||||
{
|
||||
SType = StructureType.GraphicsPipelineCreateInfo,
|
||||
StageCount = StagesCount,
|
||||
@@ -637,7 +637,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PDynamicState = &pipelineDynamicStateCreateInfo,
|
||||
Layout = PipelineLayout,
|
||||
RenderPass = renderPass,
|
||||
BasePipelineIndex = -1
|
||||
BasePipelineIndex = -1,
|
||||
};
|
||||
|
||||
gd.Api.CreateGraphicsPipelines(device, cache, 1, &pipelineCreateInfo, null, &pipelineHandle).ThrowOnError();
|
||||
@@ -659,7 +659,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
private unsafe void UpdateStageRequiredSubgroupSizes(VulkanRenderer gd, int count)
|
||||
private readonly unsafe void UpdateStageRequiredSubgroupSizes(VulkanRenderer gd, int count)
|
||||
{
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
@@ -728,7 +728,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
Stages.Dispose();
|
||||
StageRequiredSubgroupSizes.Dispose();
|
||||
|
@@ -22,12 +22,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public ulong Id8;
|
||||
public ulong Id9;
|
||||
|
||||
private uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||
private uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||
private uint ViewportsCount => (byte)((Id6 >> 54) & 0xFF);
|
||||
private uint ScissorsCount => (byte)(Id7 & 0xFF);
|
||||
private uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||
private bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||
private readonly uint VertexAttributeDescriptionsCount => (byte)((Id6 >> 38) & 0xFF);
|
||||
private readonly uint VertexBindingDescriptionsCount => (byte)((Id6 >> 46) & 0xFF);
|
||||
private readonly uint ColorBlendAttachmentStateCount => (byte)((Id7 >> 8) & 0xFF);
|
||||
private readonly bool HasDepthStencil => ((Id7 >> 63) & 0x1) != 0UL;
|
||||
|
||||
public Array32<VertexInputAttributeDescription> VertexAttributeDescriptions;
|
||||
public Array33<VertexInputBindingDescription> VertexBindingDescriptions;
|
||||
@@ -37,7 +35,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public Array9<Format> AttachmentFormats;
|
||||
public uint AttachmentIntegerFormatMask;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
public readonly override bool Equals(object obj)
|
||||
{
|
||||
return obj is PipelineUid other && Equals(other);
|
||||
}
|
||||
@@ -76,7 +74,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
private static bool SequenceEqual<T>(ReadOnlySpan<T> x, ReadOnlySpan<T> y, uint count) where T : unmanaged
|
||||
{
|
||||
return MemoryMarshal.Cast<T, byte>(x.Slice(0, (int)count)).SequenceEqual(MemoryMarshal.Cast<T, byte>(y.Slice(0, (int)count)));
|
||||
return MemoryMarshal.Cast<T, byte>(x[..(int)count]).SequenceEqual(MemoryMarshal.Cast<T, byte>(y[..(int)count]));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
@@ -23,10 +23,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
private readonly BufferHolder _buffer;
|
||||
private readonly IntPtr _bufferMap;
|
||||
private readonly CounterType _type;
|
||||
private bool _result32Bit;
|
||||
private bool _isSupported;
|
||||
private readonly bool _result32Bit;
|
||||
private readonly bool _isSupported;
|
||||
|
||||
private long _defaultValue;
|
||||
private readonly long _defaultValue;
|
||||
private int? _resetSequence;
|
||||
|
||||
public unsafe BufferedQuery(VulkanRenderer gd, Device device, PipelineFull pipeline, CounterType type, bool result32Bit)
|
||||
@@ -44,12 +44,12 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
QueryPipelineStatisticFlags flags = type == CounterType.PrimitivesGenerated ?
|
||||
QueryPipelineStatisticFlags.GeometryShaderPrimitivesBit : 0;
|
||||
|
||||
var queryPoolCreateInfo = new QueryPoolCreateInfo()
|
||||
var queryPoolCreateInfo = new QueryPoolCreateInfo
|
||||
{
|
||||
SType = StructureType.QueryPoolCreateInfo,
|
||||
QueryCount = 1,
|
||||
QueryType = GetQueryType(type),
|
||||
PipelineStatistics = flags
|
||||
PipelineStatistics = flags,
|
||||
};
|
||||
|
||||
gd.Api.CreateQueryPool(device, queryPoolCreateInfo, null, out _queryPool).ThrowOnError();
|
||||
@@ -63,14 +63,14 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
_buffer = buffer;
|
||||
}
|
||||
|
||||
private bool QueryTypeSupported(VulkanRenderer gd, CounterType type)
|
||||
private static bool QueryTypeSupported(VulkanRenderer gd, CounterType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
CounterType.SamplesPassed => true,
|
||||
CounterType.PrimitivesGenerated => gd.Capabilities.SupportsPipelineStatisticsQuery,
|
||||
CounterType.TransformFeedbackPrimitivesWritten => gd.Capabilities.SupportsTransformFeedbackQueries,
|
||||
_ => false
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
CounterType.SamplesPassed => QueryType.Occlusion,
|
||||
CounterType.PrimitivesGenerated => QueryType.PipelineStatistics,
|
||||
CounterType.TransformFeedbackPrimitivesWritten => QueryType.TransformFeedbackStreamExt,
|
||||
_ => QueryType.Occlusion
|
||||
_ => QueryType.Occlusion,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
_resetSequence = null;
|
||||
}
|
||||
|
||||
public unsafe void End(bool withResult)
|
||||
public void End(bool withResult)
|
||||
{
|
||||
if (_isSupported)
|
||||
{
|
||||
|
@@ -18,7 +18,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
public CounterType Type { get; }
|
||||
public bool Disposed { get; private set; }
|
||||
|
||||
private Queue<CounterQueueEvent> _events = new Queue<CounterQueueEvent>();
|
||||
private readonly Queue<CounterQueueEvent> _events = new();
|
||||
private CounterQueueEvent _current;
|
||||
|
||||
private ulong _accumulatedCounter;
|
||||
@@ -26,12 +26,12 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
|
||||
private readonly object _lock = new();
|
||||
|
||||
private Queue<BufferedQuery> _queryPool;
|
||||
private AutoResetEvent _queuedEvent = new AutoResetEvent(false);
|
||||
private AutoResetEvent _wakeSignal = new AutoResetEvent(false);
|
||||
private AutoResetEvent _eventConsumed = new AutoResetEvent(false);
|
||||
private readonly Queue<BufferedQuery> _queryPool;
|
||||
private readonly AutoResetEvent _queuedEvent = new(false);
|
||||
private readonly AutoResetEvent _wakeSignal = new(false);
|
||||
private readonly AutoResetEvent _eventConsumed = new(false);
|
||||
|
||||
private Thread _consumerThread;
|
||||
private readonly Thread _consumerThread;
|
||||
|
||||
public int ResetSequence { get; private set; }
|
||||
|
||||
@@ -116,10 +116,8 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
BufferedQuery result = _queryPool.Dequeue();
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new BufferedQuery(_gd, _device, _pipeline, Type, _gd.IsAmdWindows);
|
||||
}
|
||||
|
||||
return new BufferedQuery(_gd, _device, _pipeline, Type, _gd.IsAmdWindows);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,10 +16,10 @@ namespace Ryujinx.Graphics.Vulkan.Queries
|
||||
|
||||
public ulong DrawIndex { get; }
|
||||
|
||||
private CounterQueue _queue;
|
||||
private BufferedQuery _counter;
|
||||
private readonly CounterQueue _queue;
|
||||
private readonly BufferedQuery _counter;
|
||||
|
||||
private bool _hostAccessReserved = false;
|
||||
private bool _hostAccessReserved;
|
||||
private int _refCount = 1; // Starts with a reference from the counter queue.
|
||||
|
||||
private readonly object _lock = new();
|
||||
|
@@ -19,4 +19,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Access = access;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ResourceType.StorageBuffer => PipelineBase.StorageSetIndex,
|
||||
ResourceType.TextureAndSampler or ResourceType.BufferTexture => PipelineBase.TextureSetIndex,
|
||||
ResourceType.Image or ResourceType.BufferImage => PipelineBase.ImageSetIndex,
|
||||
_ => throw new ArgumentException($"Invalid resource type \"{type}\".")
|
||||
_ => throw new ArgumentException($"Invalid resource type \"{type}\"."),
|
||||
};
|
||||
|
||||
ResourceAccess access = IsReadOnlyType(type) ? ResourceAccess.Read : ResourceAccess.ReadWrite;
|
||||
@@ -64,4 +64,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return new ResourceLayout(descriptors.AsReadOnly(), usages.AsReadOnly());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@@ -8,13 +9,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly VulkanRenderer _gd;
|
||||
private readonly Auto<DisposableSampler> _sampler;
|
||||
|
||||
public unsafe SamplerHolder(VulkanRenderer gd, Device device, GAL.SamplerCreateInfo info)
|
||||
public unsafe SamplerHolder(VulkanRenderer gd, Device device, SamplerCreateInfo info)
|
||||
{
|
||||
_gd = gd;
|
||||
|
||||
gd.Samplers.Add(this);
|
||||
|
||||
(Filter minFilter, SamplerMipmapMode mipFilter) = EnumConversion.Convert(info.MinFilter);
|
||||
(Filter minFilter, SamplerMipmapMode mipFilter) = info.MinFilter.Convert();
|
||||
|
||||
float minLod = info.MinLod;
|
||||
float maxLod = info.MaxLod;
|
||||
@@ -27,7 +28,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
var borderColor = GetConstrainedBorderColor(info.BorderColor, out var cantConstrain);
|
||||
|
||||
var samplerCreateInfo = new Silk.NET.Vulkan.SamplerCreateInfo()
|
||||
var samplerCreateInfo = new Silk.NET.Vulkan.SamplerCreateInfo
|
||||
{
|
||||
SType = StructureType.SamplerCreateInfo,
|
||||
MagFilter = info.MagFilter.Convert(),
|
||||
@@ -44,7 +45,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
MinLod = minLod,
|
||||
MaxLod = maxLod,
|
||||
BorderColor = borderColor,
|
||||
UnnormalizedCoordinates = false // TODO: Use unnormalized coordinates.
|
||||
UnnormalizedCoordinates = false, // TODO: Use unnormalized coordinates.
|
||||
};
|
||||
|
||||
SamplerCustomBorderColorCreateInfoEXT customBorderColor;
|
||||
@@ -57,10 +58,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
info.BorderColor.Blue,
|
||||
info.BorderColor.Alpha);
|
||||
|
||||
customBorderColor = new SamplerCustomBorderColorCreateInfoEXT()
|
||||
customBorderColor = new SamplerCustomBorderColorCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.SamplerCustomBorderColorCreateInfoExt,
|
||||
CustomBorderColor = color
|
||||
CustomBorderColor = color,
|
||||
};
|
||||
|
||||
samplerCreateInfo.PNext = &customBorderColor;
|
||||
@@ -86,7 +87,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
cantConstrain = false;
|
||||
return BorderColor.FloatOpaqueBlack;
|
||||
}
|
||||
else if (a == 0f)
|
||||
|
||||
if (a == 0f)
|
||||
{
|
||||
cantConstrain = false;
|
||||
return BorderColor.FloatTransparentBlack;
|
||||
|
@@ -11,16 +11,16 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Device _device;
|
||||
private VkSemaphore _semaphore;
|
||||
private int _referenceCount;
|
||||
public bool _disposed;
|
||||
private bool _disposed;
|
||||
|
||||
public unsafe SemaphoreHolder(Vk api, Device device)
|
||||
{
|
||||
_api = api;
|
||||
_device = device;
|
||||
|
||||
var semaphoreCreateInfo = new SemaphoreCreateInfo()
|
||||
var semaphoreCreateInfo = new SemaphoreCreateInfo
|
||||
{
|
||||
SType = StructureType.SemaphoreCreateInfo
|
||||
SType = StructureType.SemaphoreCreateInfo,
|
||||
};
|
||||
|
||||
api.CreateSemaphore(device, in semaphoreCreateInfo, null, out _semaphore).ThrowOnError();
|
||||
|
@@ -13,7 +13,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
// The shaderc.net dependency's Options constructor and dispose are not thread safe.
|
||||
// Take this lock when using them.
|
||||
private static object _shaderOptionsLock = new object();
|
||||
private static readonly object _shaderOptionsLock = new();
|
||||
|
||||
private static readonly IntPtr _ptrMainEntryPointName = Marshal.StringToHGlobalAnsi("main");
|
||||
|
||||
@@ -57,11 +57,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (byte* pCode = spirv)
|
||||
{
|
||||
var shaderModuleCreateInfo = new ShaderModuleCreateInfo()
|
||||
var shaderModuleCreateInfo = new ShaderModuleCreateInfo
|
||||
{
|
||||
SType = StructureType.ShaderModuleCreateInfo,
|
||||
CodeSize = (uint)spirv.Length,
|
||||
PCode = (uint*)pCode
|
||||
PCode = (uint*)pCode,
|
||||
};
|
||||
|
||||
api.CreateShaderModule(device, shaderModuleCreateInfo, null, out _module).ThrowOnError();
|
||||
@@ -80,12 +80,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
options = new Options(false)
|
||||
{
|
||||
SourceLanguage = SourceLanguage.Glsl,
|
||||
TargetSpirVVersion = new SpirVVersion(1, 5)
|
||||
TargetSpirVVersion = new SpirVVersion(1, 5),
|
||||
};
|
||||
}
|
||||
|
||||
options.SetTargetEnvironment(TargetEnvironment.Vulkan, EnvironmentVersion.Vulkan_1_2);
|
||||
Compiler compiler = new Compiler(options);
|
||||
Compiler compiler = new(options);
|
||||
var scr = compiler.Compile(glsl, "Ryu", GetShaderCShaderStage(stage));
|
||||
|
||||
lock (_shaderOptionsLock)
|
||||
@@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
byte[] code = new byte[(scr.CodeLength + 3) & ~3];
|
||||
|
||||
spirvBytes.CopyTo(code.AsSpan().Slice(0, (int)scr.CodeLength));
|
||||
spirvBytes.CopyTo(code.AsSpan()[..(int)scr.CodeLength]);
|
||||
|
||||
return code;
|
||||
}
|
||||
@@ -134,12 +134,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public unsafe PipelineShaderStageCreateInfo GetInfo()
|
||||
{
|
||||
return new PipelineShaderStageCreateInfo()
|
||||
return new PipelineShaderStageCreateInfo
|
||||
{
|
||||
SType = StructureType.PipelineShaderStageCreateInfo,
|
||||
Stage = _stage,
|
||||
Module = _module,
|
||||
PName = (byte*)_ptrMainEntryPointName
|
||||
PName = (byte*)_ptrMainEntryPointName,
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -47,13 +47,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private HashTableSlim<PipelineUid, Auto<DisposablePipeline>> _graphicsPipelineCache;
|
||||
private HashTableSlim<SpecData, Auto<DisposablePipeline>> _computePipelineCache;
|
||||
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
private Device _device;
|
||||
private bool _initialized;
|
||||
|
||||
private ProgramPipelineState _state;
|
||||
private DisposableRenderPass _dummyRenderPass;
|
||||
private Task _compileTask;
|
||||
private readonly Task _compileTask;
|
||||
private bool _firstBackgroundUse;
|
||||
|
||||
public ShaderCollection(
|
||||
@@ -94,7 +94,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ShaderStageFlags.GeometryBit => 2,
|
||||
ShaderStageFlags.TessellationControlBit => 3,
|
||||
ShaderStageFlags.TessellationEvaluationBit => 4,
|
||||
_ => 0
|
||||
_ => 0,
|
||||
};
|
||||
|
||||
if (shader.StageFlags == ShaderStageFlags.ComputeBit)
|
||||
@@ -143,7 +143,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
for (int setIndex = 0; setIndex < sets.Count; setIndex++)
|
||||
{
|
||||
List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
|
||||
List<ResourceBindingSegment> currentSegments = new();
|
||||
|
||||
ResourceDescriptor currentDescriptor = default;
|
||||
int currentCount = 0;
|
||||
@@ -197,7 +197,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
for (int setIndex = 0; setIndex < setUsages.Count; setIndex++)
|
||||
{
|
||||
List<ResourceBindingSegment> currentSegments = new List<ResourceBindingSegment>();
|
||||
List<ResourceBindingSegment> currentSegments = new();
|
||||
|
||||
ResourceUsage currentUsage = default;
|
||||
int currentCount = 0;
|
||||
@@ -319,7 +319,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return _infos;
|
||||
}
|
||||
|
||||
protected unsafe DisposableRenderPass CreateDummyRenderPass()
|
||||
protected DisposableRenderPass CreateDummyRenderPass()
|
||||
{
|
||||
if (_dummyRenderPass.Value.Handle != 0)
|
||||
{
|
||||
@@ -331,7 +331,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void CreateBackgroundComputePipeline()
|
||||
{
|
||||
PipelineState pipeline = new PipelineState();
|
||||
PipelineState pipeline = new();
|
||||
pipeline.Initialize();
|
||||
|
||||
pipeline.Stages[0] = _shaders[0].GetInfo();
|
||||
@@ -484,7 +484,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return _plce.GetNewDescriptorSetCollection(gd, commandBufferIndex, setIndex, out isNew);
|
||||
}
|
||||
|
||||
protected virtual unsafe void Dispose(bool disposing)
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
|
@@ -2,8 +2,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
{
|
||||
static class ShaderBinaries
|
||||
{
|
||||
public static readonly byte[] ChangeBufferStrideShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ChangeBufferStrideShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0x00, 0x8E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x60, 0x11, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||
@@ -242,11 +241,10 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x06, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
|
||||
0x3E, 0x00, 0x03, 0x00, 0x56, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||
0x57, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x59, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00,
|
||||
0x38, 0x00, 0x01, 0x00
|
||||
0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorBlitClearAlphaFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorBlitClearAlphaFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x1B, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -290,8 +288,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x09, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorBlitFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorBlitFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -329,8 +326,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorBlitMsFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorBlitMsFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
@@ -384,8 +380,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorBlitVertexShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorBlitVertexShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x3F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -486,8 +481,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x3C, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorClearFFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorClearFFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -514,8 +508,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x0C, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorClearSIFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorClearSIFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -545,8 +538,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x0F, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorClearUIFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorClearUIFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -576,8 +568,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x0F, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorClearVertexShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorClearVertexShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x36, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -669,8 +660,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x35, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorCopyShorteningComputeShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorCopyShorteningComputeShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x79, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
@@ -801,8 +791,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorCopyToNonMsComputeShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorCopyToNonMsComputeShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x86, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
@@ -933,8 +922,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x84, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorCopyWideningComputeShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorCopyWideningComputeShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x72, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
@@ -1060,8 +1048,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0xF8, 0x00, 0x02, 0x00, 0x70, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorDrawToMsVertexShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorDrawToMsVertexShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x2E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -1133,8 +1120,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x2D, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ColorDrawToMsFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ColorDrawToMsFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||
@@ -1236,8 +1222,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ConvertD32S8ToD24S8ShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ConvertD32S8ToD24S8ShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0A, 0x00, 0x0D, 0x00, 0x77, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -1441,10 +1426,9 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x3E, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
|
||||
0x41, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00,
|
||||
0x38, 0x00, 0x01, 0x00
|
||||
};
|
||||
, };
|
||||
|
||||
public static readonly byte[] ConvertIndexBufferShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ConvertIndexBufferShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x91, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x61, 0x11, 0x00, 0x00, 0x0A, 0x00, 0x07, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x4B, 0x48, 0x52, 0x5F,
|
||||
@@ -1638,8 +1622,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] ConvertIndirectDataShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] ConvertIndirectDataShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x08, 0x00, 0x3D, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -1981,8 +1964,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0xF8, 0x00, 0x02, 0x00, 0xE5, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] DepthBlitFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] DepthBlitFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x17, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -2023,8 +2005,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] DepthBlitMsFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] DepthBlitMsFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
@@ -2081,8 +2062,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] DepthDrawToMsFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] DepthDrawToMsFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
|
||||
@@ -2185,8 +2165,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x5D, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] DepthDrawToNonMsFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] DepthDrawToNonMsFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x6A, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
|
||||
@@ -2288,8 +2267,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] StencilBlitFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] StencilBlitFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x45, 0x58, 0x54, 0x5F,
|
||||
@@ -2336,8 +2314,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x08, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] StencilBlitMsFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] StencilBlitMsFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
@@ -2399,8 +2376,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x08, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] StencilDrawToMsFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] StencilDrawToMsFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x5E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x23, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00,
|
||||
@@ -2509,8 +2485,7 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
|
||||
public static readonly byte[] StencilDrawToNonMsFragmentShaderSource = new byte[]
|
||||
{
|
||||
public static readonly byte[] StencilDrawToNonMsFragmentShaderSource = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x08, 0x00, 0x6A, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x95, 0x13, 0x00, 0x00, 0x0A, 0x00, 0x09, 0x00, 0x53, 0x50, 0x56, 0x5F, 0x45, 0x58, 0x54, 0x5F,
|
||||
@@ -2617,4 +2592,4 @@ namespace Ryujinx.Graphics.Vulkan.Shaders
|
||||
0x5F, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,5 @@
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
@@ -13,7 +11,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Int64,
|
||||
Float16,
|
||||
Float32,
|
||||
Float64
|
||||
Float64,
|
||||
}
|
||||
|
||||
sealed class SpecDescription
|
||||
@@ -36,10 +34,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
structSize += typeSize;
|
||||
}
|
||||
|
||||
Info = new SpecializationInfo()
|
||||
Info = new SpecializationInfo
|
||||
{
|
||||
DataSize = structSize,
|
||||
MapEntryCount = (uint)count
|
||||
MapEntryCount = (uint)count,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,10 +52,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
structSize = Math.Max(structSize, map[i].Offset + (uint)map[i].Size);
|
||||
}
|
||||
|
||||
Info = new SpecializationInfo()
|
||||
Info = new SpecializationInfo
|
||||
{
|
||||
DataSize = structSize,
|
||||
MapEntryCount = (uint)map.Length
|
||||
MapEntryCount = (uint)map.Length,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -66,7 +64,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SpecConstType.Int16 or SpecConstType.Float16 => 2,
|
||||
SpecConstType.Bool32 or SpecConstType.Int32 or SpecConstType.Float32 => 4,
|
||||
SpecConstType.Int64 or SpecConstType.Float64 => 8,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type))
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(type)),
|
||||
};
|
||||
|
||||
private SpecDescription()
|
||||
@@ -99,4 +97,4 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public override bool Equals(object obj) => obj is SpecData other && Equals(other);
|
||||
public bool Equals(ref SpecData other) => _data.AsSpan().SequenceEqual(other._data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_freeSize = BufferSize;
|
||||
}
|
||||
|
||||
public unsafe void PushData(CommandBufferPool cbp, CommandBufferScoped? cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
||||
public void PushData(CommandBufferPool cbp, CommandBufferScoped? cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
||||
{
|
||||
bool isRender = cbs != null;
|
||||
CommandBufferScoped scoped = cbs ?? cbp.Rent();
|
||||
@@ -72,10 +72,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
int chunkSize = Math.Min(_freeSize, data.Length);
|
||||
|
||||
PushDataImpl(scoped, dst, dstOffset, data.Slice(0, chunkSize));
|
||||
PushDataImpl(scoped, dst, dstOffset, data[..chunkSize]);
|
||||
|
||||
dstOffset += chunkSize;
|
||||
data = data.Slice(chunkSize);
|
||||
data = data[chunkSize..];
|
||||
}
|
||||
|
||||
if (!isRender)
|
||||
@@ -93,8 +93,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int capacity = BufferSize - offset;
|
||||
if (capacity < data.Length)
|
||||
{
|
||||
_buffer.SetDataUnchecked(offset, data.Slice(0, capacity));
|
||||
_buffer.SetDataUnchecked(0, data.Slice(capacity));
|
||||
_buffer.SetDataUnchecked(offset, data[..capacity]);
|
||||
_buffer.SetDataUnchecked(0, data[capacity..]);
|
||||
|
||||
BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, dstOffset, capacity);
|
||||
BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, 0, dstOffset + capacity, data.Length - capacity);
|
||||
@@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_pendingCopies.Enqueue(new PendingCopy(cbs.GetFence(), data.Length));
|
||||
}
|
||||
|
||||
public unsafe bool TryPushData(CommandBufferScoped cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
||||
public bool TryPushData(CommandBufferScoped cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan<byte> data)
|
||||
{
|
||||
if (data.Length > BufferSize)
|
||||
{
|
||||
|
@@ -21,13 +21,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
private ulong _firstHandle = 0;
|
||||
private ulong _firstHandle;
|
||||
|
||||
private readonly VulkanRenderer _gd;
|
||||
private readonly Device _device;
|
||||
private List<SyncHandle> _handles;
|
||||
private ulong FlushId;
|
||||
private long WaitTicks;
|
||||
private readonly List<SyncHandle> _handles;
|
||||
private ulong _flushId;
|
||||
private long _waitTicks;
|
||||
|
||||
public SyncManager(VulkanRenderer gd, Device device)
|
||||
{
|
||||
@@ -38,13 +38,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public void RegisterFlush()
|
||||
{
|
||||
FlushId++;
|
||||
_flushId++;
|
||||
}
|
||||
|
||||
public void Create(ulong id, bool strict)
|
||||
{
|
||||
ulong flushId = FlushId;
|
||||
MultiFenceHolder waitable = new MultiFenceHolder();
|
||||
ulong flushId = _flushId;
|
||||
MultiFenceHolder waitable = new();
|
||||
if (strict || _gd.InterruptAction == null)
|
||||
{
|
||||
_gd.FlushAllCommands();
|
||||
@@ -58,11 +58,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
_gd.CommandBufferPool.AddInUseWaitable(waitable);
|
||||
}
|
||||
|
||||
SyncHandle handle = new SyncHandle
|
||||
SyncHandle handle = new()
|
||||
{
|
||||
ID = id,
|
||||
Waitable = waitable,
|
||||
FlushId = flushId
|
||||
FlushId = flushId,
|
||||
};
|
||||
|
||||
lock (_handles)
|
||||
@@ -132,11 +132,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
long beforeTicks = Stopwatch.GetTimestamp();
|
||||
|
||||
if (result.NeedsFlush(FlushId))
|
||||
if (result.NeedsFlush(_flushId))
|
||||
{
|
||||
_gd.InterruptAction(() =>
|
||||
{
|
||||
if (result.NeedsFlush(FlushId))
|
||||
if (result.NeedsFlush(_flushId))
|
||||
{
|
||||
_gd.FlushAllCommands();
|
||||
}
|
||||
@@ -158,7 +158,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitTicks += Stopwatch.GetTimestamp() - beforeTicks;
|
||||
_waitTicks += Stopwatch.GetTimestamp() - beforeTicks;
|
||||
result.Signalled = true;
|
||||
}
|
||||
}
|
||||
@@ -177,7 +177,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
first = _handles.FirstOrDefault();
|
||||
}
|
||||
|
||||
if (first == null || first.NeedsFlush(FlushId)) break;
|
||||
if (first == null || first.NeedsFlush(_flushId))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
bool signaled = first.Waitable.WaitForFences(_gd.Api, _device, 0);
|
||||
if (signaled)
|
||||
@@ -192,7 +195,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
first.Waitable = null;
|
||||
}
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
// This sync handle and any following have not been reached yet.
|
||||
break;
|
||||
@@ -202,8 +206,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public long GetAndResetWaitTicks()
|
||||
{
|
||||
long result = WaitTicks;
|
||||
WaitTicks = 0;
|
||||
long result = _waitTicks;
|
||||
_waitTicks = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
@@ -15,7 +16,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private int _offset;
|
||||
private int _size;
|
||||
private Auto<DisposableBufferView> _bufferView;
|
||||
private Dictionary<GAL.Format, Auto<DisposableBufferView>> _selfManagedViews;
|
||||
private Dictionary<Format, Auto<DisposableBufferView>> _selfManagedViews;
|
||||
|
||||
private int _bufferCount;
|
||||
|
||||
@@ -131,15 +132,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
public BufferView GetBufferView(CommandBufferScoped cbs)
|
||||
{
|
||||
if (_bufferView == null)
|
||||
{
|
||||
_bufferView = _gd.BufferManager.CreateView(_bufferHandle, VkFormat, _offset, _size, ReleaseImpl);
|
||||
}
|
||||
_bufferView ??= _gd.BufferManager.CreateView(_bufferHandle, VkFormat, _offset, _size, ReleaseImpl);
|
||||
|
||||
return _bufferView?.Get(cbs, _offset, _size).Value ?? default;
|
||||
}
|
||||
|
||||
public BufferView GetBufferView(CommandBufferScoped cbs, GAL.Format format)
|
||||
public BufferView GetBufferView(CommandBufferScoped cbs, Format format)
|
||||
{
|
||||
var vkFormat = FormatTable.GetFormat(format);
|
||||
if (vkFormat == VkFormat)
|
||||
@@ -156,7 +154,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (bufferView != null)
|
||||
{
|
||||
(_selfManagedViews ??= new Dictionary<GAL.Format, Auto<DisposableBufferView>>()).Add(format, bufferView);
|
||||
(_selfManagedViews ??= new Dictionary<Format, Auto<DisposableBufferView>>()).Add(format, bufferView);
|
||||
}
|
||||
|
||||
return bufferView?.Get(cbs, _offset, _size).Value ?? default;
|
||||
|
@@ -80,12 +80,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
(srcOffsets.Element0, srcOffsets.Element1) = ExtentsToOffset3D(srcRegion, srcInfo.Width, srcInfo.Height, level);
|
||||
(dstOffsets.Element0, dstOffsets.Element1) = ExtentsToOffset3D(dstRegion, dstInfo.Width, dstInfo.Height, level);
|
||||
|
||||
var region = new ImageBlit()
|
||||
var region = new ImageBlit
|
||||
{
|
||||
SrcSubresource = srcSl,
|
||||
SrcOffsets = srcOffsets,
|
||||
DstSubresource = dstSl,
|
||||
DstOffsets = dstOffsets
|
||||
DstOffsets = dstOffsets,
|
||||
};
|
||||
|
||||
api.CmdBlitImage(commandBuffer, srcImage, ImageLayout.General, dstImage, ImageLayout.General, 1, region, filter);
|
||||
@@ -219,21 +219,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
int dstZ;
|
||||
int dstLayer;
|
||||
int dstDepth;
|
||||
int dstLayers;
|
||||
|
||||
if (dstInfo.Target == Target.Texture3D)
|
||||
{
|
||||
dstZ = dstDepthOrLayer;
|
||||
dstLayer = 0;
|
||||
dstDepth = depthOrLayers;
|
||||
dstLayers = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dstZ = 0;
|
||||
dstLayer = dstDepthOrLayer;
|
||||
dstDepth = 1;
|
||||
dstLayers = depthOrLayers;
|
||||
}
|
||||
|
||||
@@ -366,20 +363,20 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var dsAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 0, ImageLayout.General);
|
||||
var dsResolveAttachmentReference = new AttachmentReference2(StructureType.AttachmentReference2, null, 1, ImageLayout.General);
|
||||
|
||||
var subpassDsResolve = new SubpassDescriptionDepthStencilResolve()
|
||||
var subpassDsResolve = new SubpassDescriptionDepthStencilResolve
|
||||
{
|
||||
SType = StructureType.SubpassDescriptionDepthStencilResolve,
|
||||
PDepthStencilResolveAttachment = &dsResolveAttachmentReference,
|
||||
DepthResolveMode = ResolveModeFlags.SampleZeroBit,
|
||||
StencilResolveMode = ResolveModeFlags.SampleZeroBit
|
||||
StencilResolveMode = ResolveModeFlags.SampleZeroBit,
|
||||
};
|
||||
|
||||
var subpass = new SubpassDescription2()
|
||||
var subpass = new SubpassDescription2
|
||||
{
|
||||
SType = StructureType.SubpassDescription2,
|
||||
PipelineBindPoint = PipelineBindPoint.Graphics,
|
||||
PDepthStencilAttachment = &dsAttachmentReference,
|
||||
PNext = &subpassDsResolve
|
||||
PNext = &subpassDsResolve,
|
||||
};
|
||||
|
||||
AttachmentDescription2[] attachmentDescs = new AttachmentDescription2[2];
|
||||
@@ -414,7 +411,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
fixed (AttachmentDescription2* pAttachmentDescs = attachmentDescs)
|
||||
{
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo2()
|
||||
var renderPassCreateInfo = new RenderPassCreateInfo2
|
||||
{
|
||||
SType = StructureType.RenderPassCreateInfo2,
|
||||
PAttachments = pAttachmentDescs,
|
||||
@@ -422,7 +419,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PSubpasses = &subpass,
|
||||
SubpassCount = 1,
|
||||
PDependencies = &subpassDependency,
|
||||
DependencyCount = 1
|
||||
DependencyCount = 1,
|
||||
};
|
||||
|
||||
gd.Api.CreateRenderPass2(device, renderPassCreateInfo, null, out var renderPass).ThrowOnError();
|
||||
@@ -437,7 +434,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
attachments[0] = srcView.Get(cbs).Value;
|
||||
attachments[1] = dstView.Get(cbs).Value;
|
||||
|
||||
var framebufferCreateInfo = new FramebufferCreateInfo()
|
||||
var framebufferCreateInfo = new FramebufferCreateInfo
|
||||
{
|
||||
SType = StructureType.FramebufferCreateInfo,
|
||||
RenderPass = rp.Get(cbs).Value,
|
||||
@@ -445,23 +442,23 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PAttachments = attachments,
|
||||
Width = (uint)src.Width,
|
||||
Height = (uint)src.Height,
|
||||
Layers = (uint)src.Layers
|
||||
Layers = (uint)src.Layers,
|
||||
};
|
||||
|
||||
gd.Api.CreateFramebuffer(device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError();
|
||||
using var fb = new Auto<DisposableFramebuffer>(new DisposableFramebuffer(gd.Api, device, framebuffer), null, new[] { srcView, dstView });
|
||||
using var fb = new Auto<DisposableFramebuffer>(new DisposableFramebuffer(gd.Api, device, framebuffer), null, srcView, dstView);
|
||||
|
||||
var renderArea = new Rect2D(null, new Extent2D((uint)src.Info.Width, (uint)src.Info.Height));
|
||||
var clearValue = new ClearValue();
|
||||
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo()
|
||||
var renderPassBeginInfo = new RenderPassBeginInfo
|
||||
{
|
||||
SType = StructureType.RenderPassBeginInfo,
|
||||
RenderPass = rp.Get(cbs).Value,
|
||||
Framebuffer = fb.Get(cbs).Value,
|
||||
RenderArea = renderArea,
|
||||
PClearValues = &clearValue,
|
||||
ClearValueCount = 1
|
||||
ClearValueCount = 1,
|
||||
};
|
||||
|
||||
// The resolve operation happens at the end of the subpass, so let's just do a begin/end
|
||||
|
@@ -4,6 +4,7 @@ using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
@@ -42,7 +43,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Auto<MemoryAllocation> _allocationAuto;
|
||||
private Auto<MemoryAllocation> _foreignAllocationAuto;
|
||||
|
||||
private Dictionary<GAL.Format, TextureStorage> _aliasedStorages;
|
||||
private Dictionary<Format, TextureStorage> _aliasedStorages;
|
||||
|
||||
private AccessFlags _lastModificationAccess;
|
||||
private PipelineStageFlags _lastModificationStage;
|
||||
@@ -50,7 +51,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private PipelineStageFlags _lastReadStage;
|
||||
|
||||
private int _viewsCount;
|
||||
private ulong _size;
|
||||
private readonly ulong _size;
|
||||
|
||||
public VkFormat VkFormat { get; }
|
||||
public float ScaleFactor { get; }
|
||||
@@ -98,7 +99,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
flags |= ImageCreateFlags.Create2DArrayCompatibleBit;
|
||||
}
|
||||
|
||||
var imageCreateInfo = new ImageCreateInfo()
|
||||
var imageCreateInfo = new ImageCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageCreateInfo,
|
||||
ImageType = type,
|
||||
@@ -111,7 +112,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Usage = usage,
|
||||
SharingMode = SharingMode.Exclusive,
|
||||
InitialLayout = ImageLayout.Undefined,
|
||||
Flags = flags
|
||||
Flags = flags,
|
||||
};
|
||||
|
||||
gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError();
|
||||
@@ -150,27 +151,27 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public TextureStorage CreateAliasedColorForDepthStorageUnsafe(GAL.Format format)
|
||||
public TextureStorage CreateAliasedColorForDepthStorageUnsafe(Format format)
|
||||
{
|
||||
var colorFormat = format switch
|
||||
{
|
||||
GAL.Format.S8Uint => GAL.Format.R8Unorm,
|
||||
GAL.Format.D16Unorm => GAL.Format.R16Unorm,
|
||||
GAL.Format.S8UintD24Unorm => GAL.Format.R8G8B8A8Unorm,
|
||||
GAL.Format.D32Float => GAL.Format.R32Float,
|
||||
GAL.Format.D24UnormS8Uint => GAL.Format.R8G8B8A8Unorm,
|
||||
GAL.Format.D32FloatS8Uint => GAL.Format.R32G32Float,
|
||||
_ => throw new ArgumentException($"\"{format}\" is not a supported depth or stencil format.")
|
||||
Format.S8Uint => Format.R8Unorm,
|
||||
Format.D16Unorm => Format.R16Unorm,
|
||||
Format.S8UintD24Unorm => Format.R8G8B8A8Unorm,
|
||||
Format.D32Float => Format.R32Float,
|
||||
Format.D24UnormS8Uint => Format.R8G8B8A8Unorm,
|
||||
Format.D32FloatS8Uint => Format.R32G32Float,
|
||||
_ => throw new ArgumentException($"\"{format}\" is not a supported depth or stencil format."),
|
||||
};
|
||||
|
||||
return CreateAliasedStorageUnsafe(colorFormat);
|
||||
}
|
||||
|
||||
public TextureStorage CreateAliasedStorageUnsafe(GAL.Format format)
|
||||
public TextureStorage CreateAliasedStorageUnsafe(Format format)
|
||||
{
|
||||
if (_aliasedStorages == null || !_aliasedStorages.TryGetValue(format, out var storage))
|
||||
{
|
||||
_aliasedStorages ??= new Dictionary<GAL.Format, TextureStorage>();
|
||||
_aliasedStorages ??= new Dictionary<Format, TextureStorage>();
|
||||
|
||||
var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel);
|
||||
|
||||
@@ -182,14 +183,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return storage;
|
||||
}
|
||||
|
||||
public static TextureCreateInfo NewCreateInfoWith(ref TextureCreateInfo info, GAL.Format format, int bytesPerPixel)
|
||||
public static TextureCreateInfo NewCreateInfoWith(ref TextureCreateInfo info, Format format, int bytesPerPixel)
|
||||
{
|
||||
return NewCreateInfoWith(ref info, format, bytesPerPixel, info.Width, info.Height);
|
||||
}
|
||||
|
||||
public static TextureCreateInfo NewCreateInfoWith(
|
||||
ref TextureCreateInfo info,
|
||||
GAL.Format format,
|
||||
Format format,
|
||||
int bytesPerPixel,
|
||||
int width,
|
||||
int height)
|
||||
@@ -262,7 +263,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, (uint)_info.Levels, 0, (uint)_info.GetLayers());
|
||||
|
||||
var barrier = new ImageMemoryBarrier()
|
||||
var barrier = new ImageMemoryBarrier
|
||||
{
|
||||
SType = StructureType.ImageMemoryBarrier,
|
||||
SrcAccessMask = 0,
|
||||
@@ -272,7 +273,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||
Image = _imageAuto.Get(cbs).Value,
|
||||
SubresourceRange = subresourceRange
|
||||
SubresourceRange = subresourceRange,
|
||||
};
|
||||
|
||||
_gd.Api.CmdPipelineBarrier(
|
||||
@@ -293,7 +294,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public static ImageUsageFlags GetImageUsage(GAL.Format format, Target target, bool supportsMsStorage)
|
||||
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage)
|
||||
{
|
||||
var usage = DefaultUsageFlags;
|
||||
|
||||
|
@@ -3,6 +3,7 @@ using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Format = Ryujinx.Graphics.GAL.Format;
|
||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||
using VkFormat = Silk.NET.Vulkan.Format;
|
||||
|
||||
@@ -18,9 +19,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private readonly Auto<DisposableImageView> _imageViewDraw;
|
||||
private readonly Auto<DisposableImageView> _imageViewIdentity;
|
||||
private readonly Auto<DisposableImageView> _imageView2dArray;
|
||||
private Dictionary<GAL.Format, TextureView> _selfManagedViews;
|
||||
private Dictionary<Format, TextureView> _selfManagedViews;
|
||||
|
||||
private TextureCreateInfo _info;
|
||||
private readonly TextureCreateInfo _info;
|
||||
|
||||
public TextureCreateInfo Info => _info;
|
||||
|
||||
@@ -68,16 +69,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
var swizzleB = info.SwizzleB.Convert();
|
||||
var swizzleA = info.SwizzleA.Convert();
|
||||
|
||||
if (info.Format == GAL.Format.R5G5B5A1Unorm ||
|
||||
info.Format == GAL.Format.R5G5B5X1Unorm ||
|
||||
info.Format == GAL.Format.R5G6B5Unorm)
|
||||
if (info.Format == Format.R5G5B5A1Unorm ||
|
||||
info.Format == Format.R5G5B5X1Unorm ||
|
||||
info.Format == Format.R5G6B5Unorm)
|
||||
{
|
||||
var temp = swizzleR;
|
||||
|
||||
swizzleR = swizzleB;
|
||||
swizzleB = temp;
|
||||
(swizzleB, swizzleR) = (swizzleR, swizzleB);
|
||||
}
|
||||
else if (VkFormat == VkFormat.R4G4B4A4UnormPack16 || info.Format == GAL.Format.A1B5G5R5Unorm)
|
||||
else if (VkFormat == VkFormat.R4G4B4A4UnormPack16 || info.Format == Format.A1B5G5R5Unorm)
|
||||
{
|
||||
var tempB = swizzleB;
|
||||
var tempA = swizzleA;
|
||||
@@ -98,13 +96,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
unsafe Auto<DisposableImageView> CreateImageView(ComponentMapping cm, ImageSubresourceRange sr, ImageViewType viewType, ImageUsageFlags usageFlags)
|
||||
{
|
||||
var usage = new ImageViewUsageCreateInfo()
|
||||
var usage = new ImageViewUsageCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageViewUsageCreateInfo,
|
||||
Usage = usageFlags
|
||||
Usage = usageFlags,
|
||||
};
|
||||
|
||||
var imageCreateInfo = new ImageViewCreateInfo()
|
||||
var imageCreateInfo = new ImageViewCreateInfo
|
||||
{
|
||||
SType = StructureType.ImageViewCreateInfo,
|
||||
Image = storage.GetImageForViewCreation(),
|
||||
@@ -112,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Format = format,
|
||||
Components = cm,
|
||||
SubresourceRange = sr,
|
||||
PNext = &usage
|
||||
PNext = &usage,
|
||||
};
|
||||
|
||||
gd.Api.CreateImageView(device, imageCreateInfo, null, out var imageView).ThrowOnError();
|
||||
@@ -354,8 +352,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
return;
|
||||
}
|
||||
else if (_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitSrcBit, srcFormat) &&
|
||||
_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitDstBit, dstFormat))
|
||||
|
||||
if (_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitSrcBit, srcFormat) &&
|
||||
_gd.FormatCapabilities.OptimalFormatSupports(FormatFeatureFlags.BlitDstBit, dstFormat))
|
||||
{
|
||||
TextureCopy.Blit(
|
||||
_gd.Api,
|
||||
@@ -444,7 +443,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
int layers,
|
||||
int levels)
|
||||
{
|
||||
ImageMemoryBarrier memoryBarrier = new ImageMemoryBarrier()
|
||||
ImageMemoryBarrier memoryBarrier = new()
|
||||
{
|
||||
SType = StructureType.ImageMemoryBarrier,
|
||||
SrcAccessMask = srcAccessMask,
|
||||
@@ -454,7 +453,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Image = image,
|
||||
OldLayout = ImageLayout.General,
|
||||
NewLayout = ImageLayout.General,
|
||||
SubresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, (uint)levels, (uint)firstLayer, (uint)layers)
|
||||
SubresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, (uint)levels, (uint)firstLayer, (uint)layers),
|
||||
};
|
||||
|
||||
api.CmdPipelineBarrier(
|
||||
@@ -470,7 +469,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
memoryBarrier);
|
||||
}
|
||||
|
||||
public TextureView GetView(GAL.Format format)
|
||||
public TextureView GetView(Format format)
|
||||
{
|
||||
if (format == Info.Format)
|
||||
{
|
||||
@@ -499,7 +498,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Info.SwizzleB,
|
||||
Info.SwizzleA), 0, 0);
|
||||
|
||||
(_selfManagedViews ??= new Dictionary<GAL.Format, TextureView>()).Add(format, view);
|
||||
(_selfManagedViews ??= new Dictionary<Format, TextureView>()).Add(format, view);
|
||||
|
||||
return view;
|
||||
}
|
||||
@@ -543,10 +542,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(_gd.CommandBufferPool, resources.GetFlushBuffer()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer()));
|
||||
}
|
||||
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer()));
|
||||
}
|
||||
|
||||
public PinnedSpan<byte> GetData(int layer, int level)
|
||||
@@ -559,10 +556,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(_gd.CommandBufferPool, resources.GetFlushBuffer(), layer, level));
|
||||
}
|
||||
else
|
||||
{
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer(), layer, level));
|
||||
}
|
||||
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(GetData(resources.GetPool(), resources.GetFlushBuffer(), layer, level));
|
||||
}
|
||||
|
||||
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
||||
@@ -686,11 +681,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
return length;
|
||||
}
|
||||
|
||||
private GAL.Format GetCompatibleGalFormat(GAL.Format format)
|
||||
private Format GetCompatibleGalFormat(Format format)
|
||||
{
|
||||
if (NeedsD24S8Conversion())
|
||||
{
|
||||
return GAL.Format.D32FloatS8Uint;
|
||||
return Format.D32FloatS8Uint;
|
||||
}
|
||||
|
||||
return format;
|
||||
|
@@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
Broadcom,
|
||||
Qualcomm,
|
||||
Apple,
|
||||
Unknown
|
||||
Unknown,
|
||||
}
|
||||
|
||||
static partial class VendorUtils
|
||||
@@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
0x14E4 => Vendor.Broadcom,
|
||||
0x8086 => Vendor.Intel,
|
||||
0x5143 => Vendor.Qualcomm,
|
||||
_ => Vendor.Unknown
|
||||
_ => Vendor.Unknown,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
0x10004 => "Codeplay Software Ltd.",
|
||||
0x10005 => "Mesa",
|
||||
0x10006 => "PoCL",
|
||||
_ => $"0x{id:X}"
|
||||
_ => $"0x{id:X}",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
using BufferHandle = Ryujinx.Graphics.GAL.BufferHandle;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal struct VertexBufferState
|
||||
{
|
||||
public static VertexBufferState Null => new VertexBufferState(null, 0, 0, 0);
|
||||
public static VertexBufferState Null => new(null, 0, 0, 0);
|
||||
|
||||
private readonly int _offset;
|
||||
private readonly int _size;
|
||||
@@ -74,17 +74,15 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
autoBuffer = gd.BufferManager.GetBuffer(cbs.CommandBuffer, _handle, false, out int size);
|
||||
|
||||
// The original stride must be reapplied in case it was rewritten.
|
||||
state.Internal.VertexBindingDescriptions[DescriptorIndex].Stride = (uint)_stride;
|
||||
|
||||
if (_offset >= size)
|
||||
{
|
||||
autoBuffer = gd.BufferManager.GetBuffer(cbs.CommandBuffer, _handle, false, out int size);
|
||||
|
||||
// The original stride must be reapplied in case it was rewritten.
|
||||
state.Internal.VertexBindingDescriptions[DescriptorIndex].Stride = (uint)_stride;
|
||||
|
||||
if (_offset >= size)
|
||||
{
|
||||
autoBuffer = null;
|
||||
}
|
||||
autoBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,12 +94,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public bool BoundEquals(Auto<DisposableBuffer> buffer)
|
||||
public readonly bool BoundEquals(Auto<DisposableBuffer> buffer)
|
||||
{
|
||||
return _buffer == buffer;
|
||||
}
|
||||
|
||||
public bool Matches(Auto<DisposableBuffer> buffer, int descriptorIndex, int offset, int size, int stride = 0)
|
||||
public readonly bool Matches(Auto<DisposableBuffer> buffer, int descriptorIndex, int offset, int size, int stride = 0)
|
||||
{
|
||||
return _buffer == buffer && DescriptorIndex == descriptorIndex && _offset == offset && _size == size && _stride == stride;
|
||||
}
|
||||
@@ -117,7 +115,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public readonly void Dispose()
|
||||
{
|
||||
// Only dispose if this buffer is not refetched on each bind.
|
||||
|
||||
|
@@ -1,21 +1,19 @@
|
||||
using Silk.NET.Vulkan;
|
||||
using System;
|
||||
|
||||
using System;
|
||||
using VkBuffer = Silk.NET.Vulkan.Buffer;
|
||||
|
||||
namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
internal class VertexBufferUpdater : IDisposable
|
||||
{
|
||||
private VulkanRenderer _gd;
|
||||
private readonly VulkanRenderer _gd;
|
||||
|
||||
private uint _baseBinding;
|
||||
private uint _count;
|
||||
|
||||
private NativeArray<VkBuffer> _buffers;
|
||||
private NativeArray<ulong> _offsets;
|
||||
private NativeArray<ulong> _sizes;
|
||||
private NativeArray<ulong> _strides;
|
||||
private readonly NativeArray<VkBuffer> _buffers;
|
||||
private readonly NativeArray<ulong> _offsets;
|
||||
private readonly NativeArray<ulong> _sizes;
|
||||
private readonly NativeArray<ulong> _strides;
|
||||
|
||||
public VertexBufferUpdater(VulkanRenderer gd)
|
||||
{
|
||||
|
@@ -10,8 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
{
|
||||
class VulkanDebugMessenger : IDisposable
|
||||
{
|
||||
private static string[] _excludedMessages = new string[]
|
||||
{
|
||||
private static readonly string[] _excludedMessages = {
|
||||
// NOTE: Done on purpose right now.
|
||||
"UNASSIGNED-CoreValidation-Shader-OutputNotConsumed",
|
||||
// TODO: Figure out if fixable
|
||||
@@ -19,7 +18,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// TODO: Might be worth looking into making this happy to possibly optimize copies.
|
||||
"UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout",
|
||||
// TODO: Fix this, it's causing too much noise right now.
|
||||
"VUID-VkSubpassDependency-srcSubpass-00867"
|
||||
"VUID-VkSubpassDependency-srcSubpass-00867",
|
||||
};
|
||||
|
||||
private readonly Vk _api;
|
||||
@@ -48,7 +47,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
private Result TryInitialize(out DebugUtilsMessengerEXT? debugUtilsMessengerHandle)
|
||||
{
|
||||
debugUtilsMessengerHandle = null;
|
||||
|
||||
|
||||
if (_debugUtils != null && _logLevel != GraphicsDebugLevel.None)
|
||||
{
|
||||
var messageType = _logLevel switch
|
||||
@@ -59,7 +58,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
GraphicsDebugLevel.All => DebugUtilsMessageTypeFlagsEXT.GeneralBitExt |
|
||||
DebugUtilsMessageTypeFlagsEXT.ValidationBitExt |
|
||||
DebugUtilsMessageTypeFlagsEXT.PerformanceBitExt,
|
||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\".")
|
||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
||||
};
|
||||
|
||||
var messageSeverity = _logLevel switch
|
||||
@@ -71,14 +70,14 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
DebugUtilsMessageSeverityFlagsEXT.WarningBitExt |
|
||||
DebugUtilsMessageSeverityFlagsEXT.VerboseBitExt |
|
||||
DebugUtilsMessageSeverityFlagsEXT.ErrorBitExt,
|
||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\".")
|
||||
_ => throw new ArgumentException($"Invalid log level \"{_logLevel}\"."),
|
||||
};
|
||||
|
||||
var debugUtilsMessengerCreateInfo = new DebugUtilsMessengerCreateInfoEXT()
|
||||
var debugUtilsMessengerCreateInfo = new DebugUtilsMessengerCreateInfoEXT
|
||||
{
|
||||
SType = StructureType.DebugUtilsMessengerCreateInfoExt,
|
||||
MessageType = messageType,
|
||||
MessageSeverity = messageSeverity
|
||||
MessageSeverity = messageSeverity,
|
||||
};
|
||||
|
||||
unsafe
|
||||
|
@@ -14,14 +14,13 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
public unsafe static class VulkanInitialization
|
||||
{
|
||||
private const uint InvalidIndex = uint.MaxValue;
|
||||
private static uint MinimalVulkanVersion = Vk.Version11.Value;
|
||||
private static uint MinimalInstanceVulkanVersion = Vk.Version12.Value;
|
||||
private static uint MaximumVulkanVersion = Vk.Version12.Value;
|
||||
private static readonly uint _minimalVulkanVersion = Vk.Version11.Value;
|
||||
private static readonly uint _minimalInstanceVulkanVersion = Vk.Version12.Value;
|
||||
private static readonly uint _maximumVulkanVersion = Vk.Version12.Value;
|
||||
private const string AppName = "Ryujinx.Graphics.Vulkan";
|
||||
private const int QueuesCount = 2;
|
||||
|
||||
private static readonly string[] _desirableExtensions = new string[]
|
||||
{
|
||||
private static readonly string[] _desirableExtensions = {
|
||||
ExtConditionalRendering.ExtensionName,
|
||||
ExtExtendedDynamicState.ExtensionName,
|
||||
ExtTransformFeedback.ExtensionName,
|
||||
@@ -42,12 +41,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
"VK_NV_geometry_shader_passthrough",
|
||||
"VK_NV_viewport_array2",
|
||||
"VK_EXT_depth_clip_control",
|
||||
"VK_KHR_portability_subset" // As per spec, we should enable this if present.
|
||||
"VK_KHR_portability_subset", // As per spec, we should enable this if present.
|
||||
};
|
||||
|
||||
private static readonly string[] _requiredExtensions = new string[]
|
||||
{
|
||||
KhrSwapchain.ExtensionName
|
||||
private static readonly string[] _requiredExtensions = {
|
||||
KhrSwapchain.ExtensionName,
|
||||
};
|
||||
|
||||
internal static VulkanInstance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions)
|
||||
@@ -89,7 +87,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ApplicationVersion = 1,
|
||||
PEngineName = (byte*)appName,
|
||||
EngineVersion = 1,
|
||||
ApiVersion = MaximumVulkanVersion
|
||||
ApiVersion = _maximumVulkanVersion,
|
||||
};
|
||||
|
||||
IntPtr* ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length];
|
||||
@@ -112,7 +110,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PpEnabledExtensionNames = (byte**)ppEnabledExtensions,
|
||||
PpEnabledLayerNames = (byte**)ppEnabledLayers,
|
||||
EnabledExtensionCount = (uint)enabledExtensions.Length,
|
||||
EnabledLayerCount = (uint)enabledLayers.Count
|
||||
EnabledLayerCount = (uint)enabledLayers.Count,
|
||||
};
|
||||
|
||||
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out var instance);
|
||||
@@ -169,7 +167,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ApplicationVersion = 1,
|
||||
PEngineName = (byte*)appName,
|
||||
EngineVersion = 1,
|
||||
ApiVersion = MaximumVulkanVersion
|
||||
ApiVersion = _maximumVulkanVersion,
|
||||
};
|
||||
|
||||
var instanceCreateInfo = new InstanceCreateInfo
|
||||
@@ -179,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PpEnabledExtensionNames = null,
|
||||
PpEnabledLayerNames = null,
|
||||
EnabledExtensionCount = 0,
|
||||
EnabledLayerCount = 0
|
||||
EnabledLayerCount = 0,
|
||||
};
|
||||
|
||||
Result result = VulkanInstance.Create(api, ref instanceCreateInfo, out var rawInstance);
|
||||
@@ -192,18 +190,18 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
// We currently assume that the instance is compatible with Vulkan 1.2
|
||||
// TODO: Remove this once we relax our initialization codepaths.
|
||||
if (instance.InstanceVersion < MinimalInstanceVulkanVersion)
|
||||
if (instance.InstanceVersion < _minimalInstanceVulkanVersion)
|
||||
{
|
||||
return Array.Empty<DeviceInfo>();
|
||||
}
|
||||
|
||||
instance.EnumeratePhysicalDevices(out VulkanPhysicalDevice[] physicalDevices).ThrowOnError();
|
||||
|
||||
List<DeviceInfo> deviceInfos = new List<DeviceInfo>();
|
||||
List<DeviceInfo> deviceInfos = new();
|
||||
|
||||
foreach (VulkanPhysicalDevice physicalDevice in physicalDevices)
|
||||
{
|
||||
if (physicalDevice.PhysicalDeviceProperties.ApiVersion < MinimalVulkanVersion)
|
||||
if (physicalDevice.PhysicalDeviceProperties.ApiVersion < _minimalVulkanVersion)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -278,33 +276,33 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
queuePriorities[i] = 1f;
|
||||
}
|
||||
|
||||
var queueCreateInfo = new DeviceQueueCreateInfo()
|
||||
var queueCreateInfo = new DeviceQueueCreateInfo
|
||||
{
|
||||
SType = StructureType.DeviceQueueCreateInfo,
|
||||
QueueFamilyIndex = queueFamilyIndex,
|
||||
QueueCount = queueCount,
|
||||
PQueuePriorities = queuePriorities
|
||||
PQueuePriorities = queuePriorities,
|
||||
};
|
||||
|
||||
bool useRobustBufferAccess = VendorUtils.FromId(physicalDevice.PhysicalDeviceProperties.VendorID) == Vendor.Nvidia;
|
||||
|
||||
PhysicalDeviceFeatures2 features2 = new PhysicalDeviceFeatures2()
|
||||
PhysicalDeviceFeatures2 features2 = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceFeatures2
|
||||
SType = StructureType.PhysicalDeviceFeatures2,
|
||||
};
|
||||
|
||||
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new PhysicalDeviceVulkan11Features()
|
||||
PhysicalDeviceVulkan11Features supportedFeaturesVk11 = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
features2.PNext = &supportedFeaturesVk11;
|
||||
|
||||
PhysicalDeviceCustomBorderColorFeaturesEXT supportedFeaturesCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
||||
PhysicalDeviceCustomBorderColorFeaturesEXT supportedFeaturesCustomBorderColor = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_custom_border_color"))
|
||||
@@ -312,10 +310,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.PNext = &supportedFeaturesCustomBorderColor;
|
||||
}
|
||||
|
||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT supportedFeaturesPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT()
|
||||
PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT supportedFeaturesPrimitiveTopologyListRestart = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
||||
@@ -323,10 +321,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.PNext = &supportedFeaturesPrimitiveTopologyListRestart;
|
||||
}
|
||||
|
||||
PhysicalDeviceTransformFeedbackFeaturesEXT supportedFeaturesTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
||||
PhysicalDeviceTransformFeedbackFeaturesEXT supportedFeaturesTransformFeedback = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName))
|
||||
@@ -334,9 +332,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.PNext = &supportedFeaturesTransformFeedback;
|
||||
}
|
||||
|
||||
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||
PhysicalDeviceRobustness2FeaturesEXT supportedFeaturesRobustness2 = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt
|
||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_robustness2"))
|
||||
@@ -346,10 +344,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
features2.PNext = &supportedFeaturesRobustness2;
|
||||
}
|
||||
|
||||
PhysicalDeviceDepthClipControlFeaturesEXT supportedFeaturesDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
|
||||
PhysicalDeviceDepthClipControlFeaturesEXT supportedFeaturesDepthClipControl = new()
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
||||
PNext = features2.PNext
|
||||
PNext = features2.PNext,
|
||||
};
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control"))
|
||||
@@ -361,7 +359,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
var supportedFeatures = features2.Features;
|
||||
|
||||
var features = new PhysicalDeviceFeatures()
|
||||
var features = new PhysicalDeviceFeatures
|
||||
{
|
||||
DepthBiasClamp = supportedFeatures.DepthBiasClamp,
|
||||
DepthClamp = supportedFeatures.DepthClamp,
|
||||
@@ -383,7 +381,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
// ShaderStorageImageWriteWithoutFormat = true,
|
||||
TessellationShader = supportedFeatures.TessellationShader,
|
||||
VertexPipelineStoresAndAtomics = supportedFeatures.VertexPipelineStoresAndAtomics,
|
||||
RobustBufferAccess = useRobustBufferAccess
|
||||
RobustBufferAccess = useRobustBufferAccess,
|
||||
};
|
||||
|
||||
void* pExtendedFeatures = null;
|
||||
@@ -392,11 +390,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent(ExtTransformFeedback.ExtensionName))
|
||||
{
|
||||
featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT()
|
||||
featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
TransformFeedback = supportedFeaturesTransformFeedback.TransformFeedback
|
||||
TransformFeedback = supportedFeaturesTransformFeedback.TransformFeedback,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresTransformFeedback;
|
||||
@@ -406,12 +404,12 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_primitive_topology_list_restart"))
|
||||
{
|
||||
featuresPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT()
|
||||
featuresPrimitiveTopologyListRestart = new PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDevicePrimitiveTopologyListRestartFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
PrimitiveTopologyListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyListRestart,
|
||||
PrimitiveTopologyPatchListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyPatchListRestart
|
||||
PrimitiveTopologyPatchListRestart = supportedFeaturesPrimitiveTopologyListRestart.PrimitiveTopologyPatchListRestart,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresPrimitiveTopologyListRestart;
|
||||
@@ -421,41 +419,41 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_robustness2"))
|
||||
{
|
||||
featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT()
|
||||
featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceRobustness2FeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
NullDescriptor = supportedFeaturesRobustness2.NullDescriptor
|
||||
NullDescriptor = supportedFeaturesRobustness2.NullDescriptor,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresRobustness2;
|
||||
}
|
||||
|
||||
var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT()
|
||||
var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
ExtendedDynamicState = physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName)
|
||||
ExtendedDynamicState = physicalDevice.IsDeviceExtensionPresent(ExtExtendedDynamicState.ExtensionName),
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresExtendedDynamicState;
|
||||
|
||||
var featuresVk11 = new PhysicalDeviceVulkan11Features()
|
||||
var featuresVk11 = new PhysicalDeviceVulkan11Features
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceVulkan11Features,
|
||||
PNext = pExtendedFeatures,
|
||||
ShaderDrawParameters = supportedFeaturesVk11.ShaderDrawParameters
|
||||
ShaderDrawParameters = supportedFeaturesVk11.ShaderDrawParameters,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresVk11;
|
||||
|
||||
var featuresVk12 = new PhysicalDeviceVulkan12Features()
|
||||
var featuresVk12 = new PhysicalDeviceVulkan12Features
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceVulkan12Features,
|
||||
PNext = pExtendedFeatures,
|
||||
DescriptorIndexing = physicalDevice.IsDeviceExtensionPresent("VK_EXT_descriptor_indexing"),
|
||||
DrawIndirectCount = physicalDevice.IsDeviceExtensionPresent(KhrDrawIndirectCount.ExtensionName),
|
||||
UniformBufferStandardLayout = physicalDevice.IsDeviceExtensionPresent("VK_KHR_uniform_buffer_standard_layout")
|
||||
UniformBufferStandardLayout = physicalDevice.IsDeviceExtensionPresent("VK_KHR_uniform_buffer_standard_layout"),
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresVk12;
|
||||
@@ -464,11 +462,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_index_type_uint8"))
|
||||
{
|
||||
featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT()
|
||||
featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
IndexTypeUint8 = true
|
||||
IndexTypeUint8 = true,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresIndexU8;
|
||||
@@ -478,11 +476,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_fragment_shader_interlock"))
|
||||
{
|
||||
featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT()
|
||||
featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceFragmentShaderInterlockFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
FragmentShaderPixelInterlock = true
|
||||
FragmentShaderPixelInterlock = true,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresFragmentShaderInterlock;
|
||||
@@ -492,11 +490,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_subgroup_size_control"))
|
||||
{
|
||||
featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT()
|
||||
featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceSubgroupSizeControlFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
SubgroupSizeControl = true
|
||||
SubgroupSizeControl = true,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresSubgroupSizeControl;
|
||||
@@ -508,7 +506,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
supportedFeaturesCustomBorderColor.CustomBorderColors &&
|
||||
supportedFeaturesCustomBorderColor.CustomBorderColorWithoutFormat)
|
||||
{
|
||||
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT()
|
||||
featuresCustomBorderColor = new PhysicalDeviceCustomBorderColorFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceCustomBorderColorFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
@@ -524,11 +522,11 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_depth_clip_control") &&
|
||||
supportedFeaturesDepthClipControl.DepthClipControl)
|
||||
{
|
||||
featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT()
|
||||
featuresDepthClipControl = new PhysicalDeviceDepthClipControlFeaturesEXT
|
||||
{
|
||||
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
|
||||
PNext = pExtendedFeatures,
|
||||
DepthClipControl = true
|
||||
DepthClipControl = true,
|
||||
};
|
||||
|
||||
pExtendedFeatures = &featuresDepthClipControl;
|
||||
@@ -543,7 +541,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]);
|
||||
}
|
||||
|
||||
var deviceCreateInfo = new DeviceCreateInfo()
|
||||
var deviceCreateInfo = new DeviceCreateInfo
|
||||
{
|
||||
SType = StructureType.DeviceCreateInfo,
|
||||
PNext = pExtendedFeatures,
|
||||
@@ -551,7 +549,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||
PQueueCreateInfos = &queueCreateInfo,
|
||||
PpEnabledExtensionNames = (byte**)ppEnabledExtensions,
|
||||
EnabledExtensionCount = (uint)enabledExtensions.Length,
|
||||
PEnabledFeatures = &features
|
||||
PEnabledFeatures = &features,
|
||||
};
|
||||
|
||||
api.CreateDevice(physicalDevice.PhysicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user