diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.Graphics.Shader/StructuredIr | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Graphics.Shader/StructuredIr')
23 files changed, 0 insertions, 2331 deletions
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstAssignment.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstAssignment.cs deleted file mode 100644 index bb3fe7af..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstAssignment.cs +++ /dev/null @@ -1,35 +0,0 @@ -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstAssignment : AstNode - { - public IAstNode Destination { get; } - - private IAstNode _source; - - public IAstNode Source - { - get - { - return _source; - } - set - { - RemoveUse(_source, this); - - AddUse(value, this); - - _source = value; - } - } - - public AstAssignment(IAstNode destination, IAstNode source) - { - Destination = destination; - Source = source; - - AddDef(destination, this); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstBlock.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstBlock.cs deleted file mode 100644 index 2f34bee8..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstBlock.cs +++ /dev/null @@ -1,117 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; -using System.Collections; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstBlock : AstNode, IEnumerable<IAstNode> - { - public AstBlockType Type { get; private set; } - - private IAstNode _condition; - - public IAstNode Condition - { - get - { - return _condition; - } - set - { - RemoveUse(_condition, this); - - AddUse(value, this); - - _condition = value; - } - } - - private LinkedList<IAstNode> _nodes; - - public IAstNode First => _nodes.First?.Value; - public IAstNode Last => _nodes.Last?.Value; - - public int Count => _nodes.Count; - - public AstBlock(AstBlockType type, IAstNode condition = null) - { - Type = type; - Condition = condition; - - _nodes = new LinkedList<IAstNode>(); - } - - public void Add(IAstNode node) - { - Add(node, _nodes.AddLast(node)); - } - - public void AddFirst(IAstNode node) - { - Add(node, _nodes.AddFirst(node)); - } - - public void AddBefore(IAstNode next, IAstNode node) - { - Add(node, _nodes.AddBefore(next.LLNode, node)); - } - - public void AddAfter(IAstNode prev, IAstNode node) - { - Add(node, _nodes.AddAfter(prev.LLNode, node)); - } - - private void Add(IAstNode node, LinkedListNode<IAstNode> newNode) - { - if (node.Parent != null) - { - throw new ArgumentException("Node already belongs to a block."); - } - - node.Parent = this; - node.LLNode = newNode; - } - - public void Remove(IAstNode node) - { - _nodes.Remove(node.LLNode); - - node.Parent = null; - node.LLNode = null; - } - - public void AndCondition(IAstNode cond) - { - Condition = new AstOperation(Instruction.LogicalAnd, Condition, cond); - } - - public void OrCondition(IAstNode cond) - { - Condition = new AstOperation(Instruction.LogicalOr, Condition, cond); - } - public void TurnIntoIf(IAstNode cond) - { - Condition = cond; - - Type = AstBlockType.If; - } - - public void TurnIntoElseIf() - { - Type = AstBlockType.ElseIf; - } - - public IEnumerator<IAstNode> GetEnumerator() - { - return _nodes.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstBlockType.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstBlockType.cs deleted file mode 100644 index c12efda9..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstBlockType.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - enum AstBlockType - { - DoWhile, - If, - Else, - ElseIf, - Main, - While - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstBlockVisitor.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstBlockVisitor.cs deleted file mode 100644 index 10d5dce0..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstBlockVisitor.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstBlockVisitor - { - public AstBlock Block { get; private set; } - - public class BlockVisitationEventArgs : EventArgs - { - public AstBlock Block { get; } - - public BlockVisitationEventArgs(AstBlock block) - { - Block = block; - } - } - - public event EventHandler<BlockVisitationEventArgs> BlockEntered; - public event EventHandler<BlockVisitationEventArgs> BlockLeft; - - public AstBlockVisitor(AstBlock mainBlock) - { - Block = mainBlock; - } - - public IEnumerable<IAstNode> Visit() - { - IAstNode node = Block.First; - - while (node != null) - { - // We reached a child block, visit the nodes inside. - while (node is AstBlock childBlock) - { - Block = childBlock; - - node = childBlock.First; - - BlockEntered?.Invoke(this, new BlockVisitationEventArgs(Block)); - } - - // Node may be null, if the block is empty. - if (node != null) - { - IAstNode next = Next(node); - - yield return node; - - node = next; - } - - // We reached the end of the list, go up on tree to the parent blocks. - while (node == null && Block.Type != AstBlockType.Main) - { - BlockLeft?.Invoke(this, new BlockVisitationEventArgs(Block)); - - node = Next(Block); - - Block = Block.Parent; - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstComment.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstComment.cs deleted file mode 100644 index dabe623f..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstComment.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstComment : AstNode - { - public string Comment { get; } - - public AstComment(string comment) - { - Comment = comment; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstHelper.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstHelper.cs deleted file mode 100644 index 7aa0409b..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstHelper.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class AstHelper - { - public static void AddUse(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Uses.Add(parent); - } - } - - public static void AddDef(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Defs.Add(parent); - } - } - - public static void RemoveUse(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Uses.Remove(parent); - } - } - - public static void RemoveDef(IAstNode node, IAstNode parent) - { - if (node is AstOperand operand && operand.Type == OperandType.LocalVariable) - { - operand.Defs.Remove(parent); - } - } - - public static AstAssignment Assign(IAstNode destination, IAstNode source) - { - return new AstAssignment(destination, source); - } - - public static AstOperand Const(int value) - { - return new AstOperand(OperandType.Constant, value); - } - - public static AstOperand Local(AggregateType type) - { - AstOperand local = new AstOperand(OperandType.LocalVariable); - - local.VarType = type; - - return local; - } - - public static IAstNode InverseCond(IAstNode cond) - { - return new AstOperation(Instruction.LogicalNot, cond); - } - - public static IAstNode Next(IAstNode node) - { - return node.LLNode.Next?.Value; - } - - public static IAstNode Previous(IAstNode node) - { - return node.LLNode.Previous?.Value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstNode.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstNode.cs deleted file mode 100644 index c667aac9..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstNode.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstNode : IAstNode - { - public AstBlock Parent { get; set; } - - public LinkedListNode<IAstNode> LLNode { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstOperand.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstOperand.cs deleted file mode 100644 index 1fc0035f..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstOperand.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstOperand : AstNode - { - public HashSet<IAstNode> Defs { get; } - public HashSet<IAstNode> Uses { get; } - - public OperandType Type { get; } - - public AggregateType VarType { get; set; } - - public int Value { get; } - - public int CbufSlot { get; } - public int CbufOffset { get; } - - private AstOperand() - { - Defs = new HashSet<IAstNode>(); - Uses = new HashSet<IAstNode>(); - - VarType = AggregateType.S32; - } - - public AstOperand(Operand operand) : this() - { - Type = operand.Type; - - if (Type == OperandType.ConstantBuffer) - { - CbufSlot = operand.GetCbufSlot(); - CbufOffset = operand.GetCbufOffset(); - } - else - { - Value = operand.Value; - } - } - - public AstOperand(OperandType type, int value = 0) : this() - { - Type = type; - Value = value; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstOperation.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstOperation.cs deleted file mode 100644 index 2393fd8d..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstOperation.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System.Numerics; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstOperation : AstNode - { - public Instruction Inst { get; } - public StorageKind StorageKind { get; } - - public int Index { get; } - - private IAstNode[] _sources; - - public int SourcesCount => _sources.Length; - - public AstOperation(Instruction inst, StorageKind storageKind, IAstNode[] sources, int sourcesCount) - { - Inst = inst; - StorageKind = storageKind; - _sources = sources; - - for (int index = 0; index < sources.Length; index++) - { - if (index < sourcesCount) - { - AddUse(sources[index], this); - } - else - { - AddDef(sources[index], this); - } - } - - Index = 0; - } - - public AstOperation(Instruction inst, StorageKind storageKind, int index, IAstNode[] sources, int sourcesCount) : this(inst, storageKind, sources, sourcesCount) - { - Index = index; - } - - public AstOperation(Instruction inst, params IAstNode[] sources) : this(inst, StorageKind.None, sources, sources.Length) - { - } - - public IAstNode GetSource(int index) - { - return _sources[index]; - } - - public void SetSource(int index, IAstNode source) - { - RemoveUse(_sources[index], this); - - AddUse(source, this); - - _sources[index] = source; - } - - public AggregateType GetVectorType(AggregateType scalarType) - { - int componentsCount = BitOperations.PopCount((uint)Index); - - AggregateType type = scalarType; - - switch (componentsCount) - { - case 2: type |= AggregateType.Vector2; break; - case 3: type |= AggregateType.Vector3; break; - case 4: type |= AggregateType.Vector4; break; - } - - return type; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs deleted file mode 100644 index b71ae2c4..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs +++ /dev/null @@ -1,155 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System.Collections.Generic; -using System.Linq; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class AstOptimizer - { - public static void Optimize(StructuredProgramContext context) - { - AstBlock mainBlock = context.CurrentFunction.MainBlock; - - // When debug mode is enabled, we disable expression propagation - // (this makes comparison with the disassembly easier). - if (!context.Config.Options.Flags.HasFlag(TranslationFlags.DebugMode)) - { - AstBlockVisitor visitor = new AstBlockVisitor(mainBlock); - - foreach (IAstNode node in visitor.Visit()) - { - if (node is AstAssignment assignment && assignment.Destination is AstOperand propVar) - { - bool isWorthPropagating = propVar.Uses.Count == 1 || IsWorthPropagating(assignment.Source); - - if (propVar.Defs.Count == 1 && isWorthPropagating) - { - PropagateExpression(propVar, assignment.Source); - } - - if (propVar.Type == OperandType.LocalVariable && propVar.Uses.Count == 0) - { - visitor.Block.Remove(assignment); - - context.CurrentFunction.Locals.Remove(propVar); - } - } - } - } - - RemoveEmptyBlocks(mainBlock); - } - - private static bool IsWorthPropagating(IAstNode source) - { - if (!(source is AstOperation srcOp)) - { - return false; - } - - if (!InstructionInfo.IsUnary(srcOp.Inst)) - { - return false; - } - - return srcOp.GetSource(0) is AstOperand || srcOp.Inst == Instruction.Copy; - } - - private static void PropagateExpression(AstOperand propVar, IAstNode source) - { - IAstNode[] uses = propVar.Uses.ToArray(); - - foreach (IAstNode useNode in uses) - { - if (useNode is AstBlock useBlock) - { - useBlock.Condition = source; - } - else if (useNode is AstOperation useOperation) - { - for (int srcIndex = 0; srcIndex < useOperation.SourcesCount; srcIndex++) - { - if (useOperation.GetSource(srcIndex) == propVar) - { - useOperation.SetSource(srcIndex, source); - } - } - } - else if (useNode is AstAssignment useAssignment) - { - useAssignment.Source = source; - } - } - } - - private static void RemoveEmptyBlocks(AstBlock mainBlock) - { - Queue<AstBlock> pending = new Queue<AstBlock>(); - - pending.Enqueue(mainBlock); - - while (pending.TryDequeue(out AstBlock block)) - { - foreach (IAstNode node in block) - { - if (node is AstBlock childBlock) - { - pending.Enqueue(childBlock); - } - } - - AstBlock parent = block.Parent; - - if (parent == null) - { - continue; - } - - AstBlock nextBlock = Next(block) as AstBlock; - - bool hasElse = nextBlock != null && nextBlock.Type == AstBlockType.Else; - - bool isIf = block.Type == AstBlockType.If; - - if (block.Count == 0) - { - if (isIf) - { - if (hasElse) - { - nextBlock.TurnIntoIf(InverseCond(block.Condition)); - } - - parent.Remove(block); - } - else if (block.Type == AstBlockType.Else) - { - parent.Remove(block); - } - } - else if (isIf && parent.Type == AstBlockType.Else && parent.Count == (hasElse ? 2 : 1)) - { - AstBlock parentOfParent = parent.Parent; - - parent.Remove(block); - - parentOfParent.AddAfter(parent, block); - - if (hasElse) - { - parent.Remove(nextBlock); - - parentOfParent.AddAfter(block, nextBlock); - } - - parentOfParent.Remove(parent); - - block.TurnIntoElseIf(); - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs deleted file mode 100644 index a44f13cc..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class AstTextureOperation : AstOperation - { - public SamplerType Type { get; } - public TextureFormat Format { get; } - public TextureFlags Flags { get; } - - public int CbufSlot { get; } - public int Handle { get; } - - public AstTextureOperation( - Instruction inst, - SamplerType type, - TextureFormat format, - TextureFlags flags, - int cbufSlot, - int handle, - int index, - params IAstNode[] sources) : base(inst, StorageKind.None, index, sources, sources.Length) - { - Type = type; - Format = format; - Flags = flags; - CbufSlot = cbufSlot; - Handle = handle; - } - - public AstTextureOperation WithType(SamplerType type) - { - return new AstTextureOperation(Inst, type, Format, Flags, CbufSlot, Handle, Index); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/GotoElimination.cs b/Ryujinx.Graphics.Shader/StructuredIr/GotoElimination.cs deleted file mode 100644 index 8bcf9d9c..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/GotoElimination.cs +++ /dev/null @@ -1,459 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; -using System.Collections.Generic; - -using static Ryujinx.Graphics.Shader.StructuredIr.AstHelper; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class GotoElimination - { - // This is a modified version of the algorithm presented on the paper - // "Taming Control Flow: A Structured Approach to Eliminating Goto Statements". - public static void Eliminate(GotoStatement[] gotos) - { - for (int index = gotos.Length - 1; index >= 0; index--) - { - GotoStatement stmt = gotos[index]; - - AstBlock gBlock = ParentBlock(stmt.Goto); - AstBlock lBlock = ParentBlock(stmt.Label); - - int gLevel = Level(gBlock); - int lLevel = Level(lBlock); - - if (IndirectlyRelated(gBlock, lBlock, gLevel, lLevel)) - { - AstBlock drBlock = gBlock; - - int drLevel = gLevel; - - do - { - drBlock = drBlock.Parent; - - drLevel--; - } - while (!DirectlyRelated(drBlock, lBlock, drLevel, lLevel)); - - MoveOutward(stmt, gLevel, drLevel); - - gBlock = drBlock; - gLevel = drLevel; - - if (Previous(stmt.Goto) is AstBlock elseBlock && elseBlock.Type == AstBlockType.Else) - { - // It's possible that the label was enclosed inside an else block, - // in this case we need to update the block and level. - // We also need to set the IsLoop for the case when the label is - // now before the goto, due to the newly introduced else block. - lBlock = ParentBlock(stmt.Label); - - lLevel = Level(lBlock); - - if (!IndirectlyRelated(elseBlock, lBlock, gLevel + 1, lLevel)) - { - stmt.IsLoop = true; - } - } - } - - if (DirectlyRelated(gBlock, lBlock, gLevel, lLevel)) - { - if (gLevel > lLevel) - { - MoveOutward(stmt, gLevel, lLevel); - } - else - { - if (stmt.IsLoop) - { - Lift(stmt); - } - - MoveInward(stmt); - } - } - - gBlock = ParentBlock(stmt.Goto); - - if (stmt.IsLoop) - { - EncloseDoWhile(stmt, gBlock, stmt.Label); - } - else - { - Enclose(gBlock, AstBlockType.If, stmt.Condition, Next(stmt.Goto), stmt.Label); - } - - gBlock.Remove(stmt.Goto); - } - } - - private static bool IndirectlyRelated(AstBlock lBlock, AstBlock rBlock, int lLevel, int rlevel) - { - return !(lBlock == rBlock || DirectlyRelated(lBlock, rBlock, lLevel, rlevel)); - } - - private static bool DirectlyRelated(AstBlock lBlock, AstBlock rBlock, int lLevel, int rLevel) - { - // If the levels are equal, they can be either siblings or indirectly related. - if (lLevel == rLevel) - { - return false; - } - - IAstNode block; - IAstNode other; - - int blockLvl, otherLvl; - - if (lLevel > rLevel) - { - block = lBlock; - blockLvl = lLevel; - other = rBlock; - otherLvl = rLevel; - } - else /* if (rLevel > lLevel) */ - { - block = rBlock; - blockLvl = rLevel; - other = lBlock; - otherLvl = lLevel; - } - - while (blockLvl >= otherLvl) - { - if (block == other) - { - return true; - } - - block = block.Parent; - - blockLvl--; - } - - return false; - } - - private static void Lift(GotoStatement stmt) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label)); - - AstBlock loopFirstStmt = path[path.Length - 1]; - - if (loopFirstStmt.Type == AstBlockType.Else) - { - loopFirstStmt = Previous(loopFirstStmt) as AstBlock; - - if (loopFirstStmt == null || loopFirstStmt.Type != AstBlockType.If) - { - throw new InvalidOperationException("Found an else without a matching if."); - } - } - - AstBlock newBlock = EncloseDoWhile(stmt, block, loopFirstStmt); - - block.Remove(stmt.Goto); - - newBlock.AddFirst(stmt.Goto); - - stmt.IsLoop = false; - } - - private static void MoveOutward(GotoStatement stmt, int gLevel, int lLevel) - { - AstBlock origin = ParentBlock(stmt.Goto); - - AstBlock block = origin; - - // Check if a loop is enclosing the goto, and the block that is - // directly related to the label is above the loop block. - // In that case, we need to introduce a break to get out of the loop. - AstBlock loopBlock = origin; - - int loopLevel = gLevel; - - while (loopLevel > lLevel) - { - AstBlock child = loopBlock; - - loopBlock = loopBlock.Parent; - - loopLevel--; - - if (child.Type == AstBlockType.DoWhile) - { - EncloseSingleInst(stmt, Instruction.LoopBreak); - - block.Remove(stmt.Goto); - - loopBlock.AddAfter(child, stmt.Goto); - - block = loopBlock; - gLevel = loopLevel; - } - } - - // Insert ifs to skip the parts that shouldn't be executed due to the goto. - bool tryInsertElse = stmt.IsUnconditional && origin.Type == AstBlockType.If; - - while (gLevel > lLevel) - { - Enclose(block, AstBlockType.If, stmt.Condition, Next(stmt.Goto)); - - block.Remove(stmt.Goto); - - AstBlock child = block; - - // We can't move the goto in the middle of a if and a else block, in - // this case we need to move it after the else. - // IsLoop may need to be updated if the label is inside the else, as - // introducing a loop is the only way to ensure the else will be executed. - if (Next(child) is AstBlock elseBlock && elseBlock.Type == AstBlockType.Else) - { - child = elseBlock; - } - - block = block.Parent; - - block.AddAfter(child, stmt.Goto); - - gLevel--; - - if (tryInsertElse && child == origin) - { - AstBlock lBlock = ParentBlock(stmt.Label); - - IAstNode last = block == lBlock && !stmt.IsLoop ? stmt.Label : null; - - AstBlock newBlock = Enclose(block, AstBlockType.Else, null, Next(stmt.Goto), last); - - if (newBlock != null) - { - block.Remove(stmt.Goto); - - block.AddAfter(newBlock, stmt.Goto); - } - } - } - } - - private static void MoveInward(GotoStatement stmt) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock[] path = BackwardsPath(block, ParentBlock(stmt.Label)); - - for (int index = path.Length - 1; index >= 0; index--) - { - AstBlock child = path[index]; - AstBlock last = child; - - if (child.Type == AstBlockType.If) - { - // Modify the if condition to allow it to be entered by the goto. - if (!ContainsCondComb(child.Condition, Instruction.LogicalOr, stmt.Condition)) - { - child.OrCondition(stmt.Condition); - } - } - else if (child.Type == AstBlockType.Else) - { - // Modify the matching if condition to force the else to be entered by the goto. - if (!(Previous(child) is AstBlock ifBlock) || ifBlock.Type != AstBlockType.If) - { - throw new InvalidOperationException("Found an else without a matching if."); - } - - IAstNode cond = InverseCond(stmt.Condition); - - if (!ContainsCondComb(ifBlock.Condition, Instruction.LogicalAnd, cond)) - { - ifBlock.AndCondition(cond); - } - - last = ifBlock; - } - - Enclose(block, AstBlockType.If, stmt.Condition, Next(stmt.Goto), last); - - block.Remove(stmt.Goto); - - child.AddFirst(stmt.Goto); - - block = child; - } - } - - private static bool ContainsCondComb(IAstNode node, Instruction inst, IAstNode newCond) - { - while (node is AstOperation operation && operation.SourcesCount == 2) - { - if (operation.Inst == inst && IsSameCond(operation.GetSource(1), newCond)) - { - return true; - } - - node = operation.GetSource(0); - } - - return false; - } - - private static AstBlock EncloseDoWhile(GotoStatement stmt, AstBlock block, IAstNode first) - { - if (block.Type == AstBlockType.DoWhile && first == block.First) - { - // We only need to insert the continue if we're not at the end of the loop, - // or if our condition is different from the loop condition. - if (Next(stmt.Goto) != null || block.Condition != stmt.Condition) - { - EncloseSingleInst(stmt, Instruction.LoopContinue); - } - - // Modify the do-while condition to allow it to continue. - if (!ContainsCondComb(block.Condition, Instruction.LogicalOr, stmt.Condition)) - { - block.OrCondition(stmt.Condition); - } - - return block; - } - - return Enclose(block, AstBlockType.DoWhile, stmt.Condition, first, stmt.Goto); - } - - private static void EncloseSingleInst(GotoStatement stmt, Instruction inst) - { - AstBlock block = ParentBlock(stmt.Goto); - - AstBlock newBlock = new AstBlock(AstBlockType.If, stmt.Condition); - - block.AddAfter(stmt.Goto, newBlock); - - newBlock.AddFirst(new AstOperation(inst)); - } - - private static AstBlock Enclose( - AstBlock block, - AstBlockType type, - IAstNode cond, - IAstNode first, - IAstNode last = null) - { - if (first == last) - { - return null; - } - - if (type == AstBlockType.If) - { - cond = InverseCond(cond); - } - - // Do a quick check, if we are enclosing a single block, - // and the block type/condition matches the one we're going - // to create, then we don't need a new block, we can just - // return the old one. - bool hasSingleNode = Next(first) == last; - - if (hasSingleNode && BlockMatches(first, type, cond)) - { - return first as AstBlock; - } - - AstBlock newBlock = new AstBlock(type, cond); - - block.AddBefore(first, newBlock); - - while (first != last) - { - IAstNode next = Next(first); - - block.Remove(first); - - newBlock.Add(first); - - first = next; - } - - return newBlock; - } - - private static bool BlockMatches(IAstNode node, AstBlockType type, IAstNode cond) - { - if (!(node is AstBlock block)) - { - return false; - } - - return block.Type == type && IsSameCond(block.Condition, cond); - } - - private static bool IsSameCond(IAstNode lCond, IAstNode rCond) - { - if (lCond is AstOperation lCondOp && lCondOp.Inst == Instruction.LogicalNot) - { - if (!(rCond is AstOperation rCondOp) || rCondOp.Inst != lCondOp.Inst) - { - return false; - } - - lCond = lCondOp.GetSource(0); - rCond = rCondOp.GetSource(0); - } - - return lCond == rCond; - } - - private static AstBlock ParentBlock(IAstNode node) - { - if (node is AstBlock block) - { - return block.Parent; - } - - while (!(node is AstBlock)) - { - node = node.Parent; - } - - return node as AstBlock; - } - - private static AstBlock[] BackwardsPath(AstBlock top, AstBlock bottom) - { - AstBlock block = bottom; - - List<AstBlock> path = new List<AstBlock>(); - - while (block != top) - { - path.Add(block); - - block = block.Parent; - } - - return path.ToArray(); - } - - private static int Level(IAstNode node) - { - int level = 0; - - while (node != null) - { - level++; - - node = node.Parent; - } - - return level; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/GotoStatement.cs b/Ryujinx.Graphics.Shader/StructuredIr/GotoStatement.cs deleted file mode 100644 index 25216e55..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/GotoStatement.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class GotoStatement - { - public AstOperation Goto { get; } - public AstAssignment Label { get; } - - public IAstNode Condition => Label.Destination; - - public bool IsLoop { get; set; } - - public bool IsUnconditional => Goto.Inst == Instruction.Branch; - - public GotoStatement(AstOperation branch, AstAssignment label, bool isLoop) - { - Goto = branch; - Label = label; - IsLoop = isLoop; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs b/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs deleted file mode 100644 index d45f8d4e..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/HelperFunctionsMask.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - [Flags] - enum HelperFunctionsMask - { - AtomicMinMaxS32Shared = 1 << 0, - AtomicMinMaxS32Storage = 1 << 1, - MultiplyHighS32 = 1 << 2, - MultiplyHighU32 = 1 << 3, - Shuffle = 1 << 4, - ShuffleDown = 1 << 5, - ShuffleUp = 1 << 6, - ShuffleXor = 1 << 7, - StoreSharedSmallInt = 1 << 8, - StoreStorageSmallInt = 1 << 9, - SwizzleAdd = 1 << 10, - FSI = 1 << 11 - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/IAstNode.cs b/Ryujinx.Graphics.Shader/StructuredIr/IAstNode.cs deleted file mode 100644 index 5ececbb5..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/IAstNode.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - interface IAstNode - { - AstBlock Parent { get; set; } - - LinkedListNode<IAstNode> LLNode { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs b/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs deleted file mode 100644 index 8eccef23..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/InstructionInfo.cs +++ /dev/null @@ -1,216 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class InstructionInfo - { - private readonly struct InstInfo - { - public AggregateType DestType { get; } - - public AggregateType[] SrcTypes { get; } - - public InstInfo(AggregateType destType, params AggregateType[] srcTypes) - { - DestType = destType; - SrcTypes = srcTypes; - } - } - - private static InstInfo[] _infoTbl; - - static InstructionInfo() - { - _infoTbl = new InstInfo[(int)Instruction.Count]; - - // Inst Destination type Source 1 type Source 2 type Source 3 type Source 4 type - Add(Instruction.AtomicAdd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.AtomicAnd, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.AtomicCompareAndSwap, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32, AggregateType.U32); - Add(Instruction.AtomicMaxS32, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.AtomicMaxU32, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.AtomicMinS32, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.AtomicMinU32, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.AtomicOr, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.AtomicSwap, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.AtomicXor, AggregateType.U32, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.Absolute, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.Add, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.Ballot, AggregateType.U32, AggregateType.Bool); - Add(Instruction.BitCount, AggregateType.S32, AggregateType.S32); - Add(Instruction.BitfieldExtractS32, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.BitfieldExtractU32, AggregateType.U32, AggregateType.U32, AggregateType.S32, AggregateType.S32); - Add(Instruction.BitfieldInsert, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.BitfieldReverse, AggregateType.S32, AggregateType.S32); - Add(Instruction.BitwiseAnd, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.BitwiseExclusiveOr, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.BitwiseNot, AggregateType.S32, AggregateType.S32); - Add(Instruction.BitwiseOr, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.BranchIfTrue, AggregateType.Void, AggregateType.Bool); - Add(Instruction.BranchIfFalse, AggregateType.Void, AggregateType.Bool); - Add(Instruction.Call, AggregateType.Scalar); - Add(Instruction.Ceiling, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.Clamp, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.ClampU32, AggregateType.U32, AggregateType.U32, AggregateType.U32, AggregateType.U32); - Add(Instruction.CompareEqual, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.CompareGreater, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.CompareGreaterOrEqual, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.CompareGreaterOrEqualU32, AggregateType.Bool, AggregateType.U32, AggregateType.U32); - Add(Instruction.CompareGreaterU32, AggregateType.Bool, AggregateType.U32, AggregateType.U32); - Add(Instruction.CompareLess, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.CompareLessOrEqual, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.CompareLessOrEqualU32, AggregateType.Bool, AggregateType.U32, AggregateType.U32); - Add(Instruction.CompareLessU32, AggregateType.Bool, AggregateType.U32, AggregateType.U32); - Add(Instruction.CompareNotEqual, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.ConditionalSelect, AggregateType.Scalar, AggregateType.Bool, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.ConvertFP32ToFP64, AggregateType.FP64, AggregateType.FP32); - Add(Instruction.ConvertFP64ToFP32, AggregateType.FP32, AggregateType.FP64); - Add(Instruction.ConvertFP32ToS32, AggregateType.S32, AggregateType.FP32); - Add(Instruction.ConvertFP32ToU32, AggregateType.U32, AggregateType.FP32); - Add(Instruction.ConvertFP64ToS32, AggregateType.S32, AggregateType.FP64); - Add(Instruction.ConvertFP64ToU32, AggregateType.U32, AggregateType.FP64); - Add(Instruction.ConvertS32ToFP32, AggregateType.FP32, AggregateType.S32); - Add(Instruction.ConvertS32ToFP64, AggregateType.FP64, AggregateType.S32); - Add(Instruction.ConvertU32ToFP32, AggregateType.FP32, AggregateType.U32); - Add(Instruction.ConvertU32ToFP64, AggregateType.FP64, AggregateType.U32); - Add(Instruction.Cosine, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.Ddx, AggregateType.FP32, AggregateType.FP32); - Add(Instruction.Ddy, AggregateType.FP32, AggregateType.FP32); - Add(Instruction.Divide, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.ExponentB2, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.FindLSB, AggregateType.S32, AggregateType.S32); - Add(Instruction.FindMSBS32, AggregateType.S32, AggregateType.S32); - Add(Instruction.FindMSBU32, AggregateType.S32, AggregateType.U32); - Add(Instruction.Floor, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.FusedMultiplyAdd, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.ImageLoad, AggregateType.FP32); - Add(Instruction.ImageStore, AggregateType.Void); - Add(Instruction.ImageAtomic, AggregateType.S32); - Add(Instruction.IsNan, AggregateType.Bool, AggregateType.Scalar); - Add(Instruction.Load, AggregateType.FP32); - Add(Instruction.LoadConstant, AggregateType.FP32, AggregateType.S32, AggregateType.S32); - Add(Instruction.LoadGlobal, AggregateType.U32, AggregateType.S32, AggregateType.S32); - Add(Instruction.LoadLocal, AggregateType.U32, AggregateType.S32); - Add(Instruction.LoadShared, AggregateType.U32, AggregateType.S32); - Add(Instruction.LoadStorage, AggregateType.U32, AggregateType.S32, AggregateType.S32); - Add(Instruction.Lod, AggregateType.FP32); - Add(Instruction.LogarithmB2, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.LogicalAnd, AggregateType.Bool, AggregateType.Bool, AggregateType.Bool); - Add(Instruction.LogicalExclusiveOr, AggregateType.Bool, AggregateType.Bool, AggregateType.Bool); - Add(Instruction.LogicalNot, AggregateType.Bool, AggregateType.Bool); - Add(Instruction.LogicalOr, AggregateType.Bool, AggregateType.Bool, AggregateType.Bool); - Add(Instruction.Maximum, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.MaximumU32, AggregateType.U32, AggregateType.U32, AggregateType.U32); - Add(Instruction.Minimum, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.MinimumU32, AggregateType.U32, AggregateType.U32, AggregateType.U32); - Add(Instruction.Multiply, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.MultiplyHighS32, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.MultiplyHighU32, AggregateType.U32, AggregateType.U32, AggregateType.U32); - Add(Instruction.Negate, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.PackDouble2x32, AggregateType.FP64, AggregateType.U32, AggregateType.U32); - Add(Instruction.PackHalf2x16, AggregateType.U32, AggregateType.FP32, AggregateType.FP32); - Add(Instruction.ReciprocalSquareRoot, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.Round, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.ShiftLeft, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.ShiftRightS32, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.ShiftRightU32, AggregateType.U32, AggregateType.U32, AggregateType.S32); - Add(Instruction.Shuffle, AggregateType.FP32, AggregateType.FP32, AggregateType.U32, AggregateType.U32, AggregateType.Bool); - Add(Instruction.ShuffleDown, AggregateType.FP32, AggregateType.FP32, AggregateType.U32, AggregateType.U32, AggregateType.Bool); - Add(Instruction.ShuffleUp, AggregateType.FP32, AggregateType.FP32, AggregateType.U32, AggregateType.U32, AggregateType.Bool); - Add(Instruction.ShuffleXor, AggregateType.FP32, AggregateType.FP32, AggregateType.U32, AggregateType.U32, AggregateType.Bool); - Add(Instruction.Sine, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.SquareRoot, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.Store, AggregateType.Void); - Add(Instruction.StoreGlobal, AggregateType.Void, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.StoreLocal, AggregateType.Void, AggregateType.S32, AggregateType.U32); - Add(Instruction.StoreShared, AggregateType.Void, AggregateType.S32, AggregateType.U32); - Add(Instruction.StoreShared16, AggregateType.Void, AggregateType.S32, AggregateType.U32); - Add(Instruction.StoreShared8, AggregateType.Void, AggregateType.S32, AggregateType.U32); - Add(Instruction.StoreStorage, AggregateType.Void, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.StoreStorage16, AggregateType.Void, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.StoreStorage8, AggregateType.Void, AggregateType.S32, AggregateType.S32, AggregateType.U32); - Add(Instruction.Subtract, AggregateType.Scalar, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.SwizzleAdd, AggregateType.FP32, AggregateType.FP32, AggregateType.FP32, AggregateType.S32); - Add(Instruction.TextureSample, AggregateType.FP32); - Add(Instruction.TextureSize, AggregateType.S32, AggregateType.S32, AggregateType.S32); - Add(Instruction.Truncate, AggregateType.Scalar, AggregateType.Scalar); - Add(Instruction.UnpackDouble2x32, AggregateType.U32, AggregateType.FP64); - Add(Instruction.UnpackHalf2x16, AggregateType.FP32, AggregateType.U32); - Add(Instruction.VectorExtract, AggregateType.Scalar, AggregateType.Vector4, AggregateType.S32); - Add(Instruction.VoteAll, AggregateType.Bool, AggregateType.Bool); - Add(Instruction.VoteAllEqual, AggregateType.Bool, AggregateType.Bool); - Add(Instruction.VoteAny, AggregateType.Bool, AggregateType.Bool); - } - - private static void Add(Instruction inst, AggregateType destType, params AggregateType[] srcTypes) - { - _infoTbl[(int)inst] = new InstInfo(destType, srcTypes); - } - - public static AggregateType GetDestVarType(Instruction inst) - { - return GetFinalVarType(_infoTbl[(int)(inst & Instruction.Mask)].DestType, inst); - } - - public static AggregateType GetSrcVarType(Instruction inst, int index) - { - // TODO: Return correct type depending on source index, - // that can improve the decompiler output. - if (inst == Instruction.ImageLoad || - inst == Instruction.ImageStore || - inst == Instruction.ImageAtomic || - inst == Instruction.Lod || - inst == Instruction.TextureSample) - { - return AggregateType.FP32; - } - else if (inst == Instruction.Call || inst == Instruction.Load || inst == Instruction.Store) - { - return AggregateType.S32; - } - - return GetFinalVarType(_infoTbl[(int)(inst & Instruction.Mask)].SrcTypes[index], inst); - } - - private static AggregateType GetFinalVarType(AggregateType type, Instruction inst) - { - if (type == AggregateType.Scalar) - { - if ((inst & Instruction.FP32) != 0) - { - return AggregateType.FP32; - } - else if ((inst & Instruction.FP64) != 0) - { - return AggregateType.FP64; - } - else - { - return AggregateType.S32; - } - } - else if (type == AggregateType.Void) - { - throw new ArgumentException($"Invalid operand for instruction \"{inst}\"."); - } - - return type; - } - - public static bool IsUnary(Instruction inst) - { - if (inst == Instruction.Copy) - { - return true; - } - else if (inst == Instruction.TextureSample) - { - return false; - } - - return _infoTbl[(int)(inst & Instruction.Mask)].SrcTypes.Length == 1; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/IoDefinition.cs b/Ryujinx.Graphics.Shader/StructuredIr/IoDefinition.cs deleted file mode 100644 index 21a1b3f0..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/IoDefinition.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - readonly struct IoDefinition : IEquatable<IoDefinition> - { - public StorageKind StorageKind { get; } - public IoVariable IoVariable { get; } - public int Location { get; } - public int Component { get; } - - public IoDefinition(StorageKind storageKind, IoVariable ioVariable, int location = 0, int component = 0) - { - StorageKind = storageKind; - IoVariable = ioVariable; - Location = location; - Component = component; - } - - public override bool Equals(object other) - { - return other is IoDefinition ioDefinition && Equals(ioDefinition); - } - - public bool Equals(IoDefinition other) - { - return StorageKind == other.StorageKind && - IoVariable == other.IoVariable && - Location == other.Location && - Component == other.Component; - } - - public override int GetHashCode() - { - return (int)StorageKind | ((int)IoVariable << 8) | (Location << 16) | (Component << 24); - } - - public override string ToString() - { - return $"{StorageKind}.{IoVariable}.{Location}.{Component}"; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/OperandInfo.cs b/Ryujinx.Graphics.Shader/StructuredIr/OperandInfo.cs deleted file mode 100644 index 38ed1584..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/OperandInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class OperandInfo - { - public static AggregateType GetVarType(AstOperand operand) - { - if (operand.Type == OperandType.LocalVariable) - { - return operand.VarType; - } - else - { - return GetVarType(operand.Type); - } - } - - public static AggregateType GetVarType(OperandType type) - { - return type switch - { - OperandType.Argument => AggregateType.S32, - OperandType.Constant => AggregateType.S32, - OperandType.ConstantBuffer => AggregateType.FP32, - OperandType.Undefined => AggregateType.S32, - _ => throw new ArgumentException($"Invalid operand type \"{type}\".") - }; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/PhiFunctions.cs b/Ryujinx.Graphics.Shader/StructuredIr/PhiFunctions.cs deleted file mode 100644 index 541ca298..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/PhiFunctions.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class PhiFunctions - { - public static void Remove(BasicBlock[] blocks) - { - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - LinkedListNode<INode> node = block.Operations.First; - - while (node != null) - { - LinkedListNode<INode> nextNode = node.Next; - - if (node.Value is not PhiNode phi) - { - node = nextNode; - - continue; - } - - for (int index = 0; index < phi.SourcesCount; index++) - { - Operand src = phi.GetSource(index); - - BasicBlock srcBlock = phi.GetBlock(index); - - Operation copyOp = new Operation(Instruction.Copy, phi.Dest, src); - - srcBlock.Append(copyOp); - } - - block.Operations.Remove(node); - - node = nextNode; - } - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredFunction.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredFunction.cs deleted file mode 100644 index 61c4fed7..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredFunction.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Ryujinx.Graphics.Shader.Translation; -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class StructuredFunction - { - public AstBlock MainBlock { get; } - - public string Name { get; } - - public AggregateType ReturnType { get; } - - public AggregateType[] InArguments { get; } - public AggregateType[] OutArguments { get; } - - public HashSet<AstOperand> Locals { get; } - - public StructuredFunction( - AstBlock mainBlock, - string name, - AggregateType returnType, - AggregateType[] inArguments, - AggregateType[] outArguments) - { - MainBlock = mainBlock; - Name = name; - ReturnType = returnType; - InArguments = inArguments; - OutArguments = outArguments; - - Locals = new HashSet<AstOperand>(); - } - - public AggregateType GetArgumentType(int index) - { - return index >= InArguments.Length - ? OutArguments[index - InArguments.Length] - : InArguments[index]; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs deleted file mode 100644 index b4ca8ee5..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs +++ /dev/null @@ -1,421 +0,0 @@ -using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Collections.Generic; -using System.Numerics; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - static class StructuredProgram - { - public static StructuredProgramInfo MakeStructuredProgram(Function[] functions, ShaderConfig config) - { - StructuredProgramContext context = new StructuredProgramContext(config); - - for (int funcIndex = 0; funcIndex < functions.Length; funcIndex++) - { - Function function = functions[funcIndex]; - - BasicBlock[] blocks = function.Blocks; - - AggregateType returnType = function.ReturnsValue ? AggregateType.S32 : 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; - } - - for (int i = 0; i < outArguments.Length; i++) - { - outArguments[i] = AggregateType.S32; - } - - context.EnterFunction(blocks.Length, function.Name, returnType, inArguments, outArguments); - - PhiFunctions.Remove(blocks); - - for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) - { - BasicBlock block = blocks[blkIndex]; - - context.EnterBlock(block); - - for (LinkedListNode<INode> opNode = block.Operations.First; opNode != null; opNode = opNode.Next) - { - Operation operation = (Operation)opNode.Value; - - if (IsBranchInst(operation.Inst)) - { - context.LeaveBlock(block, operation); - } - else - { - AddOperation(context, operation); - } - } - } - - GotoElimination.Eliminate(context.GetGotos()); - - AstOptimizer.Optimize(context); - - context.LeaveFunction(); - } - - return context.Info; - } - - private static void AddOperation(StructuredProgramContext context, Operation operation) - { - Instruction inst = operation.Inst; - StorageKind storageKind = operation.StorageKind; - - if ((inst == Instruction.Load || inst == Instruction.Store) && storageKind.IsInputOrOutput()) - { - IoVariable ioVariable = (IoVariable)operation.GetSource(0).Value; - bool isOutput = storageKind.IsOutput(); - bool perPatch = storageKind.IsPerPatch(); - int location = 0; - int component = 0; - - if (context.Config.HasPerLocationInputOrOutput(ioVariable, isOutput)) - { - location = operation.GetSource(1).Value; - - if (operation.SourcesCount > 2 && - operation.GetSource(2).Type == OperandType.Constant && - context.Config.HasPerLocationInputOrOutputComponent(ioVariable, location, operation.GetSource(2).Value, isOutput)) - { - component = operation.GetSource(2).Value; - } - } - - context.Info.IoDefinitions.Add(new IoDefinition(storageKind, ioVariable, location, component)); - } - - bool vectorDest = IsVectorDestInst(inst); - - int sourcesCount = operation.SourcesCount; - int outDestsCount = operation.DestsCount != 0 && !vectorDest ? operation.DestsCount - 1 : 0; - - IAstNode[] sources = new IAstNode[sourcesCount + outDestsCount]; - - for (int index = 0; index < operation.SourcesCount; index++) - { - sources[index] = context.GetOperand(operation.GetSource(index)); - } - - for (int index = 0; index < outDestsCount; index++) - { - AstOperand oper = context.GetOperand(operation.GetDest(1 + index)); - - oper.VarType = InstructionInfo.GetSrcVarType(inst, sourcesCount + index); - - sources[sourcesCount + index] = oper; - } - - AstTextureOperation GetAstTextureOperation(TextureOperation texOp) - { - return new AstTextureOperation( - inst, - texOp.Type, - texOp.Format, - texOp.Flags, - texOp.CbufSlot, - texOp.Handle, - texOp.Index, - sources); - } - - int componentsCount = BitOperations.PopCount((uint)operation.Index); - - if (vectorDest && componentsCount > 1) - { - AggregateType destType = InstructionInfo.GetDestVarType(inst); - - IAstNode source; - - if (operation is TextureOperation texOp) - { - if (texOp.Inst == Instruction.ImageLoad) - { - destType = texOp.Format.GetComponentType(); - } - - source = GetAstTextureOperation(texOp); - } - else - { - source = new AstOperation(inst, operation.StorageKind, operation.Index, sources, operation.SourcesCount); - } - - AggregateType destElemType = destType; - - switch (componentsCount) - { - case 2: destType |= AggregateType.Vector2; break; - case 3: destType |= AggregateType.Vector3; break; - case 4: destType |= AggregateType.Vector4; break; - } - - AstOperand destVec = context.NewTemp(destType); - - context.AddNode(new AstAssignment(destVec, source)); - - for (int i = 0; i < operation.DestsCount; i++) - { - AstOperand dest = context.GetOperand(operation.GetDest(i)); - AstOperand index = new AstOperand(OperandType.Constant, i); - - dest.VarType = destElemType; - - context.AddNode(new AstAssignment(dest, new AstOperation(Instruction.VectorExtract, StorageKind.None, new[] { destVec, index }, 2))); - } - } - else if (operation.Dest != null) - { - AstOperand dest = context.GetOperand(operation.Dest); - - // If all the sources are bool, it's better to use short-circuiting - // logical operations, rather than forcing a cast to int and doing - // a bitwise operation with the value, as it is likely to be used as - // a bool in the end. - if (IsBitwiseInst(inst) && AreAllSourceTypesEqual(sources, AggregateType.Bool)) - { - inst = GetLogicalFromBitwiseInst(inst); - } - - bool isCondSel = inst == Instruction.ConditionalSelect; - bool isCopy = inst == Instruction.Copy; - - if (isCondSel || isCopy) - { - AggregateType type = GetVarTypeFromUses(operation.Dest); - - if (isCondSel && type == AggregateType.FP32) - { - inst |= Instruction.FP32; - } - - dest.VarType = type; - } - else - { - dest.VarType = InstructionInfo.GetDestVarType(inst); - } - - IAstNode source; - - if (operation is TextureOperation texOp) - { - if (texOp.Inst == Instruction.ImageLoad) - { - dest.VarType = texOp.Format.GetComponentType(); - } - - source = GetAstTextureOperation(texOp); - } - else if (!isCopy) - { - source = new AstOperation(inst, operation.StorageKind, operation.Index, sources, operation.SourcesCount); - } - else - { - source = sources[0]; - } - - context.AddNode(new AstAssignment(dest, source)); - } - else if (operation.Inst == Instruction.Comment) - { - context.AddNode(new AstComment(((CommentNode)operation).Comment)); - } - else if (operation is TextureOperation texOp) - { - AstTextureOperation astTexOp = GetAstTextureOperation(texOp); - - context.AddNode(astTexOp); - } - else - { - context.AddNode(new AstOperation(inst, operation.StorageKind, operation.Index, sources, operation.SourcesCount)); - } - - // Those instructions needs to be emulated by using helper functions, - // because they are NVIDIA specific. Those flags helps the backend to - // decide which helper functions are needed on the final generated code. - switch (operation.Inst) - { - case Instruction.AtomicMaxS32: - case Instruction.AtomicMinS32: - if (operation.StorageKind == StorageKind.SharedMemory) - { - context.Info.HelperFunctionsMask |= HelperFunctionsMask.AtomicMinMaxS32Shared; - } - else if (operation.StorageKind == StorageKind.StorageBuffer) - { - context.Info.HelperFunctionsMask |= HelperFunctionsMask.AtomicMinMaxS32Storage; - } - break; - case Instruction.MultiplyHighS32: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighS32; - break; - case Instruction.MultiplyHighU32: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.MultiplyHighU32; - break; - case Instruction.Shuffle: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.Shuffle; - break; - case Instruction.ShuffleDown: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleDown; - break; - case Instruction.ShuffleUp: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleUp; - break; - case Instruction.ShuffleXor: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.ShuffleXor; - break; - case Instruction.StoreShared16: - case Instruction.StoreShared8: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.StoreSharedSmallInt; - break; - case Instruction.StoreStorage16: - case Instruction.StoreStorage8: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.StoreStorageSmallInt; - break; - case Instruction.SwizzleAdd: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.SwizzleAdd; - break; - case Instruction.FSIBegin: - case Instruction.FSIEnd: - context.Info.HelperFunctionsMask |= HelperFunctionsMask.FSI; - break; - } - } - - private static AggregateType GetVarTypeFromUses(Operand dest) - { - HashSet<Operand> visited = new HashSet<Operand>(); - - Queue<Operand> pending = new Queue<Operand>(); - - bool Enqueue(Operand operand) - { - if (visited.Add(operand)) - { - pending.Enqueue(operand); - - return true; - } - - return false; - } - - Enqueue(dest); - - while (pending.TryDequeue(out Operand operand)) - { - foreach (INode useNode in operand.UseOps) - { - if (useNode is not Operation operation) - { - continue; - } - - if (operation.Inst == Instruction.Copy) - { - if (operation.Dest.Type == OperandType.LocalVariable) - { - if (Enqueue(operation.Dest)) - { - break; - } - } - else - { - return OperandInfo.GetVarType(operation.Dest.Type); - } - } - else - { - for (int index = 0; index < operation.SourcesCount; index++) - { - if (operation.GetSource(index) == operand) - { - return InstructionInfo.GetSrcVarType(operation.Inst, index); - } - } - } - } - } - - return AggregateType.S32; - } - - private static bool AreAllSourceTypesEqual(IAstNode[] sources, AggregateType type) - { - foreach (IAstNode node in sources) - { - if (node is not AstOperand operand) - { - return false; - } - - if (operand.VarType != type) - { - return false; - } - } - - return true; - } - - private static bool IsVectorDestInst(Instruction inst) - { - return inst switch - { - Instruction.ImageLoad or - Instruction.TextureSample => true, - _ => false - }; - } - - private static bool IsBranchInst(Instruction inst) - { - return inst switch - { - Instruction.Branch or - Instruction.BranchIfFalse or - Instruction.BranchIfTrue => true, - _ => false - }; - } - - private static bool IsBitwiseInst(Instruction inst) - { - return inst switch - { - Instruction.BitwiseAnd or - Instruction.BitwiseExclusiveOr or - Instruction.BitwiseNot or - Instruction.BitwiseOr => true, - _ => false - }; - } - - private static Instruction GetLogicalFromBitwiseInst(Instruction inst) - { - return inst switch - { - Instruction.BitwiseAnd => Instruction.LogicalAnd, - Instruction.BitwiseExclusiveOr => Instruction.LogicalExclusiveOr, - Instruction.BitwiseNot => Instruction.LogicalNot, - Instruction.BitwiseOr => Instruction.LogicalOr, - _ => throw new ArgumentException($"Unexpected instruction \"{inst}\".") - }; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs deleted file mode 100644 index 68bbdeb1..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs +++ /dev/null @@ -1,330 +0,0 @@ -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; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - class StructuredProgramContext - { - private HashSet<BasicBlock> _loopTails; - - private Stack<(AstBlock Block, int CurrEndIndex, int LoopEndIndex)> _blockStack; - - private Dictionary<Operand, AstOperand> _localsMap; - - private Dictionary<int, AstAssignment> _gotoTempAsgs; - - private List<GotoStatement> _gotos; - - private AstBlock _currBlock; - - private int _currEndIndex; - private int _loopEndIndex; - - public StructuredFunction CurrentFunction { get; private set; } - - public StructuredProgramInfo Info { get; } - - public ShaderConfig Config { get; } - - public StructuredProgramContext(ShaderConfig config) - { - Info = new StructuredProgramInfo(); - - Config = config; - - if (config.GpPassthrough) - { - int passthroughAttributes = config.PassthroughAttributes; - while (passthroughAttributes != 0) - { - int index = BitOperations.TrailingZeroCount(passthroughAttributes); - - Info.IoDefinitions.Add(new IoDefinition(StorageKind.Input, IoVariable.UserDefined, index)); - - passthroughAttributes &= ~(1 << index); - } - - Info.IoDefinitions.Add(new IoDefinition(StorageKind.Input, IoVariable.Position)); - Info.IoDefinitions.Add(new IoDefinition(StorageKind.Input, IoVariable.PointSize)); - Info.IoDefinitions.Add(new IoDefinition(StorageKind.Input, IoVariable.ClipDistance)); - } - else if (config.Stage == ShaderStage.Fragment) - { - // Potentially used for texture coordinate scaling. - Info.IoDefinitions.Add(new IoDefinition(StorageKind.Input, IoVariable.FragmentCoord)); - } - } - - public void EnterFunction( - int blocksCount, - string name, - AggregateType returnType, - AggregateType[] inArguments, - AggregateType[] outArguments) - { - _loopTails = new HashSet<BasicBlock>(); - - _blockStack = new Stack<(AstBlock, int, int)>(); - - _localsMap = new Dictionary<Operand, AstOperand>(); - - _gotoTempAsgs = new Dictionary<int, AstAssignment>(); - - _gotos = new List<GotoStatement>(); - - _currBlock = new AstBlock(AstBlockType.Main); - - _currEndIndex = blocksCount; - _loopEndIndex = blocksCount; - - CurrentFunction = new StructuredFunction(_currBlock, name, returnType, inArguments, outArguments); - } - - public void LeaveFunction() - { - Info.Functions.Add(CurrentFunction); - } - - public void EnterBlock(BasicBlock block) - { - while (_currEndIndex == block.Index) - { - (_currBlock, _currEndIndex, _loopEndIndex) = _blockStack.Pop(); - } - - if (_gotoTempAsgs.TryGetValue(block.Index, out AstAssignment gotoTempAsg)) - { - AddGotoTempReset(block, gotoTempAsg); - } - - LookForDoWhileStatements(block); - } - - public void LeaveBlock(BasicBlock block, Operation branchOp) - { - LookForIfStatements(block, branchOp); - } - - private void LookForDoWhileStatements(BasicBlock block) - { - // Check if we have any predecessor whose index is greater than the - // current block, this indicates a loop. - bool done = false; - - foreach (BasicBlock predecessor in block.Predecessors.OrderByDescending(x => x.Index)) - { - // If not a loop, break. - if (predecessor.Index < block.Index) - { - break; - } - - // Check if we can create a do-while loop here (only possible if the loop end - // falls inside the current scope), if not add a goto instead. - if (predecessor.Index < _currEndIndex && !done) - { - // Create do-while loop block. We must avoid inserting a goto at the end - // of the loop later, when the tail block is processed. So we add the predecessor - // to a list of loop tails to prevent it from being processed later. - Operation branchOp = (Operation)predecessor.GetLastOp(); - - NewBlock(AstBlockType.DoWhile, branchOp, predecessor.Index + 1); - - _loopTails.Add(predecessor); - - done = true; - } - else - { - // Failed to create loop. Since this block is the loop head, we reset the - // goto condition variable here. The variable is always reset on the jump - // target, and this block is the jump target for some loop. - AddGotoTempReset(block, GetGotoTempAsg(block.Index)); - - break; - } - } - } - - private void LookForIfStatements(BasicBlock block, Operation branchOp) - { - if (block.Branch == null) - { - return; - } - - // We can only enclose the "if" when the branch lands before - // the end of the current block. If the current enclosing block - // is not a loop, then we can also do so if the branch lands - // right at the end of the current block. When it is a loop, - // this is not valid as the loop condition would be evaluated, - // and it could erroneously jump back to the start of the loop. - bool inRange = - block.Branch.Index < _currEndIndex || - (block.Branch.Index == _currEndIndex && block.Branch.Index < _loopEndIndex); - - bool isLoop = block.Branch.Index <= block.Index; - - if (inRange && !isLoop) - { - NewBlock(AstBlockType.If, branchOp, block.Branch.Index); - } - else if (!_loopTails.Contains(block)) - { - AstAssignment gotoTempAsg = GetGotoTempAsg(block.Branch.Index); - - // We use DoWhile type here, as the condition should be true for - // unconditional branches, or it should jump if the condition is true otherwise. - IAstNode cond = GetBranchCond(AstBlockType.DoWhile, branchOp); - - AddNode(Assign(gotoTempAsg.Destination, cond)); - - AstOperation branch = new AstOperation(branchOp.Inst); - - AddNode(branch); - - GotoStatement gotoStmt = new GotoStatement(branch, gotoTempAsg, isLoop); - - _gotos.Add(gotoStmt); - } - } - - private AstAssignment GetGotoTempAsg(int index) - { - if (_gotoTempAsgs.TryGetValue(index, out AstAssignment gotoTempAsg)) - { - return gotoTempAsg; - } - - AstOperand gotoTemp = NewTemp(AggregateType.Bool); - - gotoTempAsg = Assign(gotoTemp, Const(IrConsts.False)); - - _gotoTempAsgs.Add(index, gotoTempAsg); - - return gotoTempAsg; - } - - private void AddGotoTempReset(BasicBlock block, AstAssignment gotoTempAsg) - { - // If it was already added, we don't need to add it again. - if (gotoTempAsg.Parent != null) - { - return; - } - - AddNode(gotoTempAsg); - - // For block 0, we don't need to add the extra "reset" at the beginning, - // because it is already the first node to be executed on the shader, - // so it is reset to false by the "local" assignment anyway. - if (block.Index != 0) - { - CurrentFunction.MainBlock.AddFirst(Assign(gotoTempAsg.Destination, Const(IrConsts.False))); - } - } - - private void NewBlock(AstBlockType type, Operation branchOp, int endIndex) - { - NewBlock(type, GetBranchCond(type, branchOp), endIndex); - } - - private void NewBlock(AstBlockType type, IAstNode cond, int endIndex) - { - AstBlock childBlock = new AstBlock(type, cond); - - AddNode(childBlock); - - _blockStack.Push((_currBlock, _currEndIndex, _loopEndIndex)); - - _currBlock = childBlock; - _currEndIndex = endIndex; - - if (type == AstBlockType.DoWhile) - { - _loopEndIndex = endIndex; - } - } - - private IAstNode GetBranchCond(AstBlockType type, Operation branchOp) - { - IAstNode cond; - - if (branchOp.Inst == Instruction.Branch) - { - // If the branch is not conditional, the condition is a constant. - // For if it's false (always jump over, if block never executed). - // For loops it's always true (always loop). - cond = Const(type == AstBlockType.If ? IrConsts.False : IrConsts.True); - } - else - { - cond = GetOperand(branchOp.GetSource(0)); - - Instruction invInst = type == AstBlockType.If - ? Instruction.BranchIfTrue - : Instruction.BranchIfFalse; - - if (branchOp.Inst == invInst) - { - cond = new AstOperation(Instruction.LogicalNot, cond); - } - } - - return cond; - } - - public void AddNode(IAstNode node) - { - _currBlock.Add(node); - } - - public GotoStatement[] GetGotos() - { - return _gotos.ToArray(); - } - - public AstOperand NewTemp(AggregateType type) - { - AstOperand newTemp = Local(type); - - CurrentFunction.Locals.Add(newTemp); - - return newTemp; - } - - public AstOperand GetOperand(Operand operand) - { - if (operand == null) - { - return null; - } - - if (operand.Type != OperandType.LocalVariable) - { - if (operand.Type == OperandType.ConstantBuffer) - { - Config.SetUsedConstantBuffer(operand.GetCbufSlot()); - } - - return new AstOperand(operand); - } - - if (!_localsMap.TryGetValue(operand, out AstOperand astOperand)) - { - astOperand = new AstOperand(operand); - - _localsMap.Add(operand, astOperand); - - CurrentFunction.Locals.Add(astOperand); - } - - return astOperand; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs deleted file mode 100644 index c5104146..00000000 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.Graphics.Shader.StructuredIr -{ - readonly struct TransformFeedbackOutput - { - public readonly bool Valid; - public readonly int Buffer; - public readonly int Offset; - public readonly int Stride; - - public TransformFeedbackOutput(int buffer, int offset, int stride) - { - Valid = true; - Buffer = buffer; - Offset = offset; - Stride = stride; - } - } - - class StructuredProgramInfo - { - public List<StructuredFunction> Functions { get; } - - public HashSet<IoDefinition> IoDefinitions { get; } - - public HelperFunctionsMask HelperFunctionsMask { get; set; } - - public StructuredProgramInfo() - { - Functions = new List<StructuredFunction>(); - - IoDefinitions = new HashSet<IoDefinition>(); - } - } -}
\ No newline at end of file |
