diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-08-16 18:16:25 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-16 23:16:25 +0200 |
commit | 17354d59d14680258186168c1c462654665ee8c7 (patch) | |
tree | 0c92f76d961d6a0257fa4c56132b1f1520cfc590 /src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs | |
parent | 0c445184c185f6cd4b870d88b5eaad46c633b83b (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.cs | 86 |
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( |