diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2024-05-14 11:47:16 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-14 16:47:16 +0200 |
| commit | 3a3b51893ee272af49d762387da5b27743786d56 (patch) | |
| tree | e37f41f9a6cd65f8c9f53359b378740b6fbe00af /src/Ryujinx.Graphics.Shader | |
| parent | 44dbab3848c8831d27e50f7252d759a2494ad556 (diff) | |
Add support for bindless textures from storage buffer on Vulkan (#6721)
* Halve primitive ID when converting quads to triangles
* Shader cache version bump
* Add support for bindless textures from storage buffer on Vulkan
Diffstat (limited to 'src/Ryujinx.Graphics.Shader')
5 files changed, 24 insertions, 3 deletions
diff --git a/src/Ryujinx.Graphics.Shader/GpuGraphicsState.cs b/src/Ryujinx.Graphics.Shader/GpuGraphicsState.cs index f16c71d5..38684002 100644 --- a/src/Ryujinx.Graphics.Shader/GpuGraphicsState.cs +++ b/src/Ryujinx.Graphics.Shader/GpuGraphicsState.cs @@ -103,6 +103,11 @@ namespace Ryujinx.Graphics.Shader public readonly bool OriginUpperLeft; /// <summary> + /// Indicates that the primitive ID values on the shader should be halved due to quad to triangles conversion. + /// </summary> + public readonly bool HalvePrimitiveId; + + /// <summary> /// Creates a new GPU graphics state. /// </summary> /// <param name="earlyZForce">Early Z force enable</param> @@ -124,6 +129,7 @@ namespace Ryujinx.Graphics.Shader /// <param name="dualSourceBlendEnable">Indicates whether dual source blend is enabled</param> /// <param name="yNegateEnabled">Indicates if negation of the viewport Y axis is enabled</param> /// <param name="originUpperLeft">If true, indicates that the fragment origin is the upper left corner of the viewport, otherwise it is the lower left corner</param> + /// <param name="halvePrimitiveId">Indicates that the primitive ID values on the shader should be halved due to quad to triangles conversion</param> public GpuGraphicsState( bool earlyZForce, InputTopology topology, @@ -143,7 +149,8 @@ namespace Ryujinx.Graphics.Shader in Array8<AttributeType> fragmentOutputTypes, bool dualSourceBlendEnable, bool yNegateEnabled, - bool originUpperLeft) + bool originUpperLeft, + bool halvePrimitiveId) { EarlyZForce = earlyZForce; Topology = topology; @@ -164,6 +171,7 @@ namespace Ryujinx.Graphics.Shader DualSourceBlendEnable = dualSourceBlendEnable; YNegateEnabled = yNegateEnabled; OriginUpperLeft = originUpperLeft; + HalvePrimitiveId = halvePrimitiveId; } } } diff --git a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs index b1a9f9f8..3dc4ad90 100644 --- a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs +++ b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs @@ -135,6 +135,7 @@ namespace Ryujinx.Graphics.Shader default, false, false, + false, false); } diff --git a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs index 63ce38e2..c704156b 100644 --- a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs +++ b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs @@ -84,6 +84,10 @@ namespace Ryujinx.Graphics.Shader.Instructions value = context.IConvertU32ToFP32(value); } } + else if (offset == AttributeConsts.PrimitiveId && context.TranslatorContext.Definitions.HalvePrimitiveId) + { + value = context.ShiftRightS32(value, Const(1)); + } context.Copy(Register(rd), value); } @@ -187,6 +191,12 @@ namespace Ryujinx.Graphics.Shader.Instructions } } } + else if (op.Imm10 == AttributeConsts.PrimitiveId && context.TranslatorContext.Definitions.HalvePrimitiveId) + { + // If quads are used, but the host does not support them, they need to be converted to triangles. + // Since each quad becomes 2 triangles, we need to compensate here and divide primitive ID by 2. + res = context.ShiftRightS32(res, Const(1)); + } else if (op.Imm10 == AttributeConsts.FrontFacing && context.TranslatorContext.GpuAccessor.QueryHostHasFrontFacingBug()) { // gl_FrontFacing sometimes has incorrect (flipped) values depending how it is accessed on Intel GPUs. diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs index 22321543..4128af24 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs @@ -66,9 +66,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations if (nvHandle.AsgOp is not Operation handleOp || handleOp.Inst != Instruction.Load || - handleOp.StorageKind != StorageKind.Input) + (handleOp.StorageKind != StorageKind.Input && handleOp.StorageKind != StorageKind.StorageBuffer)) { - // Right now, we only allow bindless access when the handle comes from a shader input. + // Right now, we only allow bindless access when the handle comes from a shader input or storage buffer. // This is an artificial limitation to prevent it from being used in cases where it // would have a large performance impact of loading all textures in the pool. // It might be removed in the future, if we can mitigate the performance impact. diff --git a/src/Ryujinx.Graphics.Shader/Translation/ShaderDefinitions.cs b/src/Ryujinx.Graphics.Shader/Translation/ShaderDefinitions.cs index 3246e259..f831ec94 100644 --- a/src/Ryujinx.Graphics.Shader/Translation/ShaderDefinitions.cs +++ b/src/Ryujinx.Graphics.Shader/Translation/ShaderDefinitions.cs @@ -45,6 +45,8 @@ namespace Ryujinx.Graphics.Shader.Translation public bool YNegateEnabled => _graphicsState.YNegateEnabled; public bool OriginUpperLeft => _graphicsState.OriginUpperLeft; + public bool HalvePrimitiveId => _graphicsState.HalvePrimitiveId; + public ImapPixelType[] ImapTypes { get; } public bool IaIndexing { get; private set; } public bool OaIndexing { get; private set; } |
