diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-10-04 19:46:11 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-04 19:46:11 -0300 |
commit | a0af6e4d07f623692943c5fe68b183365b38c812 (patch) | |
tree | c8bec298b2671a8a1cc205a2cee6c5a583655173 /src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs | |
parent | f61b7818c3330fa0cda3fcde5b1de51b1477bfa0 (diff) |
Use unique temporary variables for function call parameters on SPIR-V (#5757)1.1.1041
* Use unique temporary variables for function call parameters on SPIR-V
* Shader cache version bump
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs index b0db0ffb..f28bb6aa 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs @@ -8,11 +8,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { static class StructuredProgram { + // TODO: Eventually it should be possible to specify the parameter types for the function instead of using S32 for everything. + private const AggregateType FuncParameterType = AggregateType.S32; + public static StructuredProgramInfo MakeStructuredProgram( IReadOnlyList<Function> functions, AttributeUsage attributeUsage, ShaderDefinitions definitions, ResourceManager resourceManager, + TargetLanguage targetLanguage, bool debugMode) { StructuredProgramContext context = new(attributeUsage, definitions, resourceManager, debugMode); @@ -23,19 +27,19 @@ namespace Ryujinx.Graphics.Shader.StructuredIr BasicBlock[] blocks = function.Blocks; - AggregateType returnType = function.ReturnsValue ? AggregateType.S32 : AggregateType.Void; + AggregateType returnType = function.ReturnsValue ? FuncParameterType : AggregateType.Void; AggregateType[] inArguments = new AggregateType[function.InArgumentsCount]; AggregateType[] outArguments = new AggregateType[function.OutArgumentsCount]; for (int i = 0; i < inArguments.Length; i++) { - inArguments[i] = AggregateType.S32; + inArguments[i] = FuncParameterType; } for (int i = 0; i < outArguments.Length; i++) { - outArguments[i] = AggregateType.S32; + outArguments[i] = FuncParameterType; } context.EnterFunction(blocks.Length, function.Name, returnType, inArguments, outArguments); @@ -58,7 +62,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr } else { - AddOperation(context, operation); + AddOperation(context, operation, targetLanguage); } } } @@ -73,7 +77,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr return context.Info; } - private static void AddOperation(StructuredProgramContext context, Operation operation) + private static void AddOperation(StructuredProgramContext context, Operation operation, TargetLanguage targetLanguage) { Instruction inst = operation.Inst; StorageKind storageKind = operation.StorageKind; @@ -114,9 +118,28 @@ namespace Ryujinx.Graphics.Shader.StructuredIr IAstNode[] sources = new IAstNode[sourcesCount + outDestsCount]; - for (int index = 0; index < operation.SourcesCount; index++) + if (inst == Instruction.Call && targetLanguage == TargetLanguage.Spirv) + { + // SPIR-V requires that all function parameters are copied to a local variable before the call + // (or at least that's what the Khronos compiler does). + + // First one is the function index. + sources[0] = context.GetOperandOrCbLoad(operation.GetSource(0)); + + // Remaining ones are parameters, copy them to a temp local variable. + for (int index = 1; index < operation.SourcesCount; index++) + { + AstOperand argTemp = context.NewTemp(FuncParameterType); + context.AddNode(new AstAssignment(argTemp, context.GetOperandOrCbLoad(operation.GetSource(index)))); + sources[index] = argTemp; + } + } + else { - sources[index] = context.GetOperandOrCbLoad(operation.GetSource(index)); + for (int index = 0; index < operation.SourcesCount; index++) + { + sources[index] = context.GetOperandOrCbLoad(operation.GetSource(index)); + } } for (int index = 0; index < outDestsCount; index++) |