Add workaround for conditional exit, and fix half float instruction with constant buffer

This commit is contained in:
gdkchan 2019-04-09 23:53:50 -03:00
commit fa5ef1a34b
4 changed files with 20 additions and 7 deletions

View file

@ -307,6 +307,11 @@ namespace Ryujinx.Graphics.Shader.Decoders
private static bool IsUnconditional(OpCode opCode) private static bool IsUnconditional(OpCode opCode)
{ {
if (opCode is OpCodeExit op && op.Condition != Condition.Always)
{
return false;
}
return opCode.Predicate.Index == RegisterConsts.PredicateTrueIndex && !opCode.InvertPredicate; return opCode.Predicate.Index == RegisterConsts.PredicateTrueIndex && !opCode.InvertPredicate;
} }

View file

@ -4,9 +4,11 @@ namespace Ryujinx.Graphics.Shader.Decoders
{ {
class OpCodeExit : OpCode class OpCodeExit : OpCode
{ {
public Condition Condition { get; }
public OpCodeExit(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) public OpCodeExit(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
{ {
Condition = (Condition)opCode.Extract(0, 5);
} }
} }
} }

View file

@ -292,20 +292,19 @@ namespace Ryujinx.Graphics.Shader.Instructions
FPHalfSwizzle swizzle = FPHalfSwizzle.FP16; FPHalfSwizzle swizzle = FPHalfSwizzle.FP16;
if (!(op is IOpCodeImm))
{
swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(28, 2);
}
bool absoluteB = false, negateB = false; bool absoluteB = false, negateB = false;
if (op is IOpCodeReg) if (op is IOpCodeReg)
{ {
swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(28, 2);
absoluteB = op.RawOpCode.Extract(30); absoluteB = op.RawOpCode.Extract(30);
negateB = op.RawOpCode.Extract(31); negateB = op.RawOpCode.Extract(31);
} }
else if (op is IOpCodeCbuf) else if (op is IOpCodeCbuf)
{ {
swizzle = FPHalfSwizzle.FP32;
absoluteB = op.RawOpCode.Extract(54); absoluteB = op.RawOpCode.Extract(54);
} }

View file

@ -16,9 +16,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
} }
public static void Exit(EmitterContext context) public static void Exit(EmitterContext context)
{
OpCodeExit op = (OpCodeExit)context.CurrOp;
//TODO: Figure out how this is supposed to work in the
//presence of other condition codes.
if (op.Condition == Condition.Always)
{ {
context.Return(); context.Return();
} }
}
public static void Kil(EmitterContext context) public static void Kil(EmitterContext context)
{ {