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 | |
| 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')
| -rw-r--r-- | Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs | 4 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs | 32 |
2 files changed, 31 insertions, 5 deletions
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs index 1f6f389d..1d3a1101 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs @@ -288,7 +288,9 @@ namespace Ryujinx.Graphics.Shader.Instructions context.Copy(dest, res); } - // TODO: CC, X + SetZnFlags(context, res, op.SetCondCode, op.Extended); + + // TODO: X } public static void Isetp(EmitterContext context) 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 |
