aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2024-05-14 11:47:16 -0300
committerGitHub <noreply@github.com>2024-05-14 16:47:16 +0200
commit3a3b51893ee272af49d762387da5b27743786d56 (patch)
treee37f41f9a6cd65f8c9f53359b378740b6fbe00af /src/Ryujinx.Graphics.Shader
parent44dbab3848c8831d27e50f7252d759a2494ad556 (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')
-rw-r--r--src/Ryujinx.Graphics.Shader/GpuGraphicsState.cs10
-rw-r--r--src/Ryujinx.Graphics.Shader/IGpuAccessor.cs1
-rw-r--r--src/Ryujinx.Graphics.Shader/Instructions/InstEmitAttribute.cs10
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs4
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/ShaderDefinitions.cs2
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; }