diff options
Diffstat (limited to 'Ryujinx.Graphics.Shader/StructuredIr')
7 files changed, 86 insertions, 34 deletions
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstBlock.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstBlock.cs index fdef87de..2f34bee8 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstBlock.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/AstBlock.cs @@ -32,6 +32,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr private LinkedList<IAstNode> _nodes; public IAstNode First => _nodes.First?.Value; + public IAstNode Last => _nodes.Last?.Value; public int Count => _nodes.Count; diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs index c4d8370c..b71ae2c4 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs @@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr // When debug mode is enabled, we disable expression propagation // (this makes comparison with the disassembly easier). - if ((context.Config.Options.Flags & TranslationFlags.DebugMode) == 0) + if (!context.Config.Options.Flags.HasFlag(TranslationFlags.DebugMode)) { AstBlockVisitor visitor = new AstBlockVisitor(mainBlock); diff --git a/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs b/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs index 3dfd025b..d45f8d4e 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs @@ -15,6 +15,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr ShuffleXor = 1 << 7, StoreSharedSmallInt = 1 << 8, StoreStorageSmallInt = 1 << 9, - SwizzleAdd = 1 << 10 + SwizzleAdd = 1 << 10, + FSI = 1 << 11 } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/PhiFunctions.cs b/Ryujinx.Graphics.Shader/StructuredIr/PhiFunctions.cs index 53391b62..541ca298 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/PhiFunctions.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/PhiFunctions.cs @@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { LinkedListNode<INode> nextNode = node.Next; - if (!(node.Value is PhiNode phi)) + if (node.Value is not PhiNode phi) { node = nextNode; @@ -32,7 +32,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr Operation copyOp = new Operation(Instruction.Copy, phi.Dest, src); - AddBeforeBranch(srcBlock, copyOp); + srcBlock.Append(copyOp); } block.Operations.Remove(node); @@ -41,34 +41,5 @@ namespace Ryujinx.Graphics.Shader.StructuredIr } } } - - private static void AddBeforeBranch(BasicBlock block, INode node) - { - INode lastOp = block.GetLastOp(); - - if (lastOp is Operation operation && IsControlFlowInst(operation.Inst)) - { - block.Operations.AddBefore(block.Operations.Last, node); - } - else - { - block.Operations.AddLast(node); - } - } - - private static bool IsControlFlowInst(Instruction inst) - { - switch (inst) - { - case Instruction.Branch: - case Instruction.BranchIfFalse: - case Instruction.BranchIfTrue: - case Instruction.Discard: - case Instruction.Return: - return true; - } - - return false; - } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs index ce79f3b8..9d8e64bf 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs @@ -64,7 +64,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr context.LeaveFunction(); } - if (config.TransformFeedbackEnabled) + if (config.TransformFeedbackEnabled && config.LastInVertexPipeline) { for (int tfbIndex = 0; tfbIndex < 4; tfbIndex++) { @@ -89,6 +89,18 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { Instruction inst = operation.Inst; + if (inst == Instruction.LoadAttribute) + { + Operand src1 = operation.GetSource(0); + Operand src2 = operation.GetSource(1); + + if (src1.Type == OperandType.Constant && src2.Type == OperandType.Constant) + { + int attrOffset = (src1.Value & AttributeConsts.Mask) + (src2.Value << 2); + context.Info.Inputs.Add(attrOffset); + } + } + int sourcesCount = operation.SourcesCount; int outDestsCount = operation.DestsCount != 0 ? operation.DestsCount - 1 : 0; @@ -232,6 +244,10 @@ namespace Ryujinx.Graphics.Shader.StructuredIr case Instruction.SwizzleAdd: context.Info.HelperFunctionsMask |= HelperFunctionsMask.SwizzleAdd; break; + case Instruction.FSIBegin: + case Instruction.FSIEnd: + context.Info.HelperFunctionsMask |= HelperFunctionsMask.FSI; + break; } } diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs index 05325144..4d2fdb54 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs @@ -2,6 +2,7 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.Translation; using System.Collections.Generic; using System.Linq; +using System.Numerics; using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; @@ -35,6 +36,40 @@ namespace Ryujinx.Graphics.Shader.StructuredIr Info = new StructuredProgramInfo(); Config = config; + + if (config.GpPassthrough) + { + int passthroughAttributes = config.PassthroughAttributes; + while (passthroughAttributes != 0) + { + int index = BitOperations.TrailingZeroCount(passthroughAttributes); + + int attrBase = AttributeConsts.UserAttributeBase + index * 16; + Info.Inputs.Add(attrBase); + Info.Inputs.Add(attrBase + 4); + Info.Inputs.Add(attrBase + 8); + Info.Inputs.Add(attrBase + 12); + + passthroughAttributes &= ~(1 << index); + } + + Info.Inputs.Add(AttributeConsts.PositionX); + Info.Inputs.Add(AttributeConsts.PositionY); + Info.Inputs.Add(AttributeConsts.PositionZ); + Info.Inputs.Add(AttributeConsts.PositionW); + Info.Inputs.Add(AttributeConsts.PointSize); + + for (int i = 0; i < 8; i++) + { + Info.Inputs.Add(AttributeConsts.ClipDistance0 + i * 4); + } + } + else if (config.Stage == ShaderStage.Fragment) + { + // Potentially used for texture coordinate scaling. + Info.Inputs.Add(AttributeConsts.PositionX); + Info.Inputs.Add(AttributeConsts.PositionY); + } } public void EnterFunction( @@ -277,6 +312,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr public AstOperand GetOperandDef(Operand operand) { + if (operand.Type == OperandType.Attribute) + { + Info.Outputs.Add(operand.Value & AttributeConsts.Mask); + } + else if (operand.Type == OperandType.AttributePerPatch) + { + Info.OutputsPerPatch.Add(operand.Value & AttributeConsts.Mask); + } + return GetOperand(operand); } @@ -288,6 +332,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr return GetOperandDef(operand); } + if (operand.Type == OperandType.Attribute) + { + Info.Inputs.Add(operand.Value); + } + else if (operand.Type == OperandType.AttributePerPatch) + { + Info.InputsPerPatch.Add(operand.Value); + } + return GetOperand(operand); } diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs index 2dc23964..43bdfaba 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs @@ -22,6 +22,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { public List<StructuredFunction> Functions { get; } + public HashSet<int> Inputs { get; } + public HashSet<int> Outputs { get; } + public HashSet<int> InputsPerPatch { get; } + public HashSet<int> OutputsPerPatch { get; } + public HelperFunctionsMask HelperFunctionsMask { get; set; } public TransformFeedbackOutput[] TransformFeedbackOutputs { get; } @@ -30,6 +35,11 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { Functions = new List<StructuredFunction>(); + Inputs = new HashSet<int>(); + Outputs = new HashSet<int>(); + InputsPerPatch = new HashSet<int>(); + OutputsPerPatch = new HashSet<int>(); + TransformFeedbackOutputs = new TransformFeedbackOutput[0xc0]; } } |