diff options
author | gdk <gab.dark.100@gmail.com> | 2019-11-27 00:38:56 -0300 |
---|---|---|
committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
commit | 442485adb32626b3931cd15f284d0e686b0021fc (patch) | |
tree | 65791c99024c3c7e27088ce6740efabf2f0276dc /Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs | |
parent | 99f236fcf03e4304a91df70c3545b9b79ff15942 (diff) |
Partial support for branch with CC, and fix a edge case of branch out of loop on shaders
Diffstat (limited to 'Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs index 03ff8818..55958a12 100644 --- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs +++ b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgramContext.cs @@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { private HashSet<BasicBlock> _loopTails; - private Stack<(AstBlock Block, int EndIndex)> _blockStack; + private Stack<(AstBlock Block, int CurrEndIndex, int LoopEndIndex)> _blockStack; private Dictionary<Operand, AstOperand> _localsMap; @@ -22,6 +22,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr private AstBlock _currBlock; private int _currEndIndex; + private int _loopEndIndex; public StructuredProgramInfo Info { get; } @@ -31,7 +32,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { _loopTails = new HashSet<BasicBlock>(); - _blockStack = new Stack<(AstBlock, int)>(); + _blockStack = new Stack<(AstBlock, int, int)>(); _localsMap = new Dictionary<Operand, AstOperand>(); @@ -42,6 +43,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr _currBlock = new AstBlock(AstBlockType.Main); _currEndIndex = blocksCount; + _loopEndIndex = blocksCount; Info = new StructuredProgramInfo(_currBlock); @@ -52,7 +54,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr { while (_currEndIndex == block.Index) { - (_currBlock, _currEndIndex) = _blockStack.Pop(); + (_currBlock, _currEndIndex, _loopEndIndex) = _blockStack.Pop(); } if (_gotoTempAsgs.TryGetValue(block.Index, out AstAssignment gotoTempAsg)) @@ -107,9 +109,19 @@ namespace Ryujinx.Graphics.Shader.StructuredIr 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 (block.Branch.Index <= _currEndIndex && !isLoop) + if (inRange && !isLoop) { NewBlock(AstBlockType.If, branchOp, block.Branch.Index); } @@ -171,10 +183,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr AddNode(childBlock); - _blockStack.Push((_currBlock, _currEndIndex)); + _blockStack.Push((_currBlock, _currEndIndex, _loopEndIndex)); _currBlock = childBlock; _currEndIndex = endIndex; + + if (type == AstBlockType.DoWhile) + { + _loopEndIndex = endIndex; + } } private IAstNode GetBranchCond(AstBlockType type, Operation branchOp) |