aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-08-16 18:16:25 -0300
committerGitHub <noreply@github.com>2023-08-16 23:16:25 +0200
commit17354d59d14680258186168c1c462654665ee8c7 (patch)
tree0c92f76d961d6a0257fa4c56132b1f1520cfc590 /src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
parent0c445184c185f6cd4b870d88b5eaad46c633b83b (diff)
Declare and use gl_PerVertex block for VTG per-vertex built-ins (#5576)1.1.993
* Declare and use gl_PerVertex block for VTG per-vertex built-ins * Shader cache version bump
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs')
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
index f3a083c3..153a6940 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
@@ -348,12 +348,98 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
}
}
}
+ else if (IoMap.IsPerVertexBuiltIn(ioDefinition.IoVariable))
+ {
+ continue;
+ }
bool isOutput = ioDefinition.StorageKind.IsOutput();
bool isPerPatch = ioDefinition.StorageKind.IsPerPatch();
DeclareInputOrOutput(context, ioDefinition, isOutput, isPerPatch, iq, firstLocation);
}
+
+ DeclarePerVertexBlock(context);
+ }
+
+ private static void DeclarePerVertexBlock(CodeGenContext context)
+ {
+ if (context.Definitions.Stage.IsVtg())
+ {
+ if (context.Definitions.Stage != ShaderStage.Vertex)
+ {
+ var perVertexInputStructType = CreatePerVertexStructType(context);
+ int arraySize = context.Definitions.Stage == ShaderStage.Geometry ? context.InputVertices : 32;
+ var perVertexInputArrayType = context.TypeArray(perVertexInputStructType, context.Constant(context.TypeU32(), arraySize));
+ var perVertexInputPointerType = context.TypePointer(StorageClass.Input, perVertexInputArrayType);
+ var perVertexInputVariable = context.Variable(perVertexInputPointerType, StorageClass.Input);
+
+ context.Name(perVertexInputVariable, "gl_in");
+
+ context.AddGlobalVariable(perVertexInputVariable);
+ context.Inputs.Add(new IoDefinition(StorageKind.Input, IoVariable.Position), perVertexInputVariable);
+ }
+
+ var perVertexOutputStructType = CreatePerVertexStructType(context);
+
+ void DecorateTfo(IoVariable ioVariable, int fieldIndex)
+ {
+ if (context.Definitions.TryGetTransformFeedbackOutput(ioVariable, 0, 0, out var transformFeedbackOutput))
+ {
+ context.MemberDecorate(perVertexOutputStructType, fieldIndex, Decoration.XfbBuffer, (LiteralInteger)transformFeedbackOutput.Buffer);
+ context.MemberDecorate(perVertexOutputStructType, fieldIndex, Decoration.XfbStride, (LiteralInteger)transformFeedbackOutput.Stride);
+ context.MemberDecorate(perVertexOutputStructType, fieldIndex, Decoration.Offset, (LiteralInteger)transformFeedbackOutput.Offset);
+ }
+ }
+
+ DecorateTfo(IoVariable.Position, 0);
+ DecorateTfo(IoVariable.PointSize, 1);
+ DecorateTfo(IoVariable.ClipDistance, 2);
+
+ SpvInstruction perVertexOutputArrayType;
+
+ if (context.Definitions.Stage == ShaderStage.TessellationControl)
+ {
+ int arraySize = context.Definitions.ThreadsPerInputPrimitive;
+ perVertexOutputArrayType = context.TypeArray(perVertexOutputStructType, context.Constant(context.TypeU32(), arraySize));
+ }
+ else
+ {
+ perVertexOutputArrayType = perVertexOutputStructType;
+ }
+
+ var perVertexOutputPointerType = context.TypePointer(StorageClass.Output, perVertexOutputArrayType);
+ var perVertexOutputVariable = context.Variable(perVertexOutputPointerType, StorageClass.Output);
+
+ context.AddGlobalVariable(perVertexOutputVariable);
+ context.Outputs.Add(new IoDefinition(StorageKind.Output, IoVariable.Position), perVertexOutputVariable);
+ }
+ }
+
+ private static SpvInstruction CreatePerVertexStructType(CodeGenContext context)
+ {
+ var vec4FloatType = context.TypeVector(context.TypeFP32(), 4);
+ var floatType = context.TypeFP32();
+ var array8FloatType = context.TypeArray(context.TypeFP32(), context.Constant(context.TypeU32(), 8));
+ var array1FloatType = context.TypeArray(context.TypeFP32(), context.Constant(context.TypeU32(), 1));
+
+ var perVertexStructType = context.TypeStruct(true, vec4FloatType, floatType, array8FloatType, array1FloatType);
+
+ context.Name(perVertexStructType, "gl_PerVertex");
+
+ context.MemberName(perVertexStructType, 0, "gl_Position");
+ context.MemberName(perVertexStructType, 1, "gl_PointSize");
+ context.MemberName(perVertexStructType, 2, "gl_ClipDistance");
+ context.MemberName(perVertexStructType, 3, "gl_CullDistance");
+
+ context.Decorate(perVertexStructType, Decoration.Block);
+
+ context.MemberDecorate(perVertexStructType, 0, Decoration.BuiltIn, (LiteralInteger)BuiltIn.Position);
+ context.MemberDecorate(perVertexStructType, 1, Decoration.BuiltIn, (LiteralInteger)BuiltIn.PointSize);
+ context.MemberDecorate(perVertexStructType, 2, Decoration.BuiltIn, (LiteralInteger)BuiltIn.ClipDistance);
+ context.MemberDecorate(perVertexStructType, 3, Decoration.BuiltIn, (LiteralInteger)BuiltIn.CullDistance);
+
+ return perVertexStructType;
}
private static void DeclareInputOrOutput(