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/Instructions/InstEmitFlow.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/Instructions/InstEmitFlow.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs index 4a9f5f7f..c024fe02 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs @@ -4,6 +4,7 @@ using Ryujinx.Graphics.Shader.Translation; using System.Collections.Generic; using System.Linq; +using static Ryujinx.Graphics.Shader.Instructions.InstEmitHelper; using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper; namespace Ryujinx.Graphics.Shader.Instructions @@ -129,22 +130,29 @@ namespace Ryujinx.Graphics.Shader.Instructions private static void EmitBranch(EmitterContext context, ulong address) { + OpCode op = context.CurrOp; + // If we're branching to the next instruction, then the branch // is useless and we can ignore it. - if (address == context.CurrOp.Address + 8) + if (address == op.Address + 8) { return; } Operand label = context.GetLabel(address); - Operand pred = Register(context.CurrOp.Predicate); + Operand pred = Register(op.Predicate); - if (context.CurrOp.Predicate.IsPT) + if (op is OpCodeBranch opBranch && opBranch.Condition != Condition.Always) + { + pred = context.BitwiseAnd(pred, GetCondition(context, opBranch.Condition)); + } + + if (op.Predicate.IsPT) { context.Branch(label); } - else if (context.CurrOp.InvertPredicate) + else if (op.InvertPredicate) { context.BranchIfFalse(label, pred); } @@ -153,5 +161,21 @@ namespace Ryujinx.Graphics.Shader.Instructions context.BranchIfTrue(label, pred); } } + + private static Operand GetCondition(EmitterContext context, Condition cond) + { + // TODO: More condition codes, figure out how they work. + switch (cond) + { + case Condition.Equal: + case Condition.EqualUnordered: + return GetZF(context); + case Condition.NotEqual: + case Condition.NotEqualUnordered: + return context.BitwiseNot(GetZF(context)); + } + + return Const(IrConsts.True); + } } }
\ No newline at end of file |