aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-11-27 00:38:56 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit442485adb32626b3931cd15f284d0e686b0021fc (patch)
tree65791c99024c3c7e27088ce6740efabf2f0276dc /Ryujinx.Graphics.Shader/Instructions/InstEmitFlow.cs
parent99f236fcf03e4304a91df70c3545b9b79ff15942 (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.cs32
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