From fa5ef1a34bb1e9242dd1ce910084784f9d341de4 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 9 Apr 2019 23:53:50 -0300 Subject: [PATCH] Add workaround for conditional exit, and fix half float instruction with constant buffer --- Ryujinx.Graphics/Shader/Decoders/Decoder.cs | 5 +++++ Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs | 4 +++- Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs | 9 ++++----- Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs | 9 ++++++++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Ryujinx.Graphics/Shader/Decoders/Decoder.cs b/Ryujinx.Graphics/Shader/Decoders/Decoder.cs index 836927a595..63fb7c6d87 100644 --- a/Ryujinx.Graphics/Shader/Decoders/Decoder.cs +++ b/Ryujinx.Graphics/Shader/Decoders/Decoder.cs @@ -307,6 +307,11 @@ namespace Ryujinx.Graphics.Shader.Decoders 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; } diff --git a/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs b/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs index 886dbff44f..d50903eb4f 100644 --- a/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs +++ b/Ryujinx.Graphics/Shader/Decoders/OpCodeExit.cs @@ -4,9 +4,11 @@ namespace Ryujinx.Graphics.Shader.Decoders { class OpCodeExit : OpCode { + public Condition Condition { get; } + public OpCodeExit(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { - + Condition = (Condition)opCode.Extract(0, 5); } } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs index a643c44690..5fb72cfffe 100644 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs +++ b/Ryujinx.Graphics/Shader/Instructions/InstEmitFArith.cs @@ -292,20 +292,19 @@ namespace Ryujinx.Graphics.Shader.Instructions FPHalfSwizzle swizzle = FPHalfSwizzle.FP16; - if (!(op is IOpCodeImm)) - { - swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(28, 2); - } - bool absoluteB = false, negateB = false; if (op is IOpCodeReg) { + swizzle = (FPHalfSwizzle)op.RawOpCode.Extract(28, 2); + absoluteB = op.RawOpCode.Extract(30); negateB = op.RawOpCode.Extract(31); } else if (op is IOpCodeCbuf) { + swizzle = FPHalfSwizzle.FP32; + absoluteB = op.RawOpCode.Extract(54); } diff --git a/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs b/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs index 1cd705d624..c4523f75cf 100644 --- a/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs +++ b/Ryujinx.Graphics/Shader/Instructions/InstEmitFlow.cs @@ -17,7 +17,14 @@ namespace Ryujinx.Graphics.Shader.Instructions public static void Exit(EmitterContext context) { - context.Return(); + 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(); + } } public static void Kil(EmitterContext context)