Partial support for branch with CC, and fix a edge case of branch out of loop on shaders

This commit is contained in:
gdk 2019-11-27 00:38:56 -03:00 committed by Thog
parent 99f236fcf0
commit 442485adb3
5 changed files with 60 additions and 14 deletions

View file

@ -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);
}
}
}