aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/StructuredIr
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Shader/StructuredIr')
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/AstBlock.cs1
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs2
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs3
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/PhiFunctions.cs33
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs18
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs53
-rw-r--r--Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs10
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];
}
}