From e0c95b18eb225d62301b8e3c3fe9d4f689381100 Mon Sep 17 00:00:00 2001 From: gdk Date: Sun, 24 Nov 2019 19:49:56 -0300 Subject: [PATCH] Add PSET shader instruction --- .../{OpCodePsetp.cs => OpCodePset.cs} | 10 ++++- .../Decoders/OpCodeTable.cs | 5 ++- .../Instructions/InstEmitAlu.cs | 37 +++++++++++++++---- 3 files changed, 41 insertions(+), 11 deletions(-) rename Ryujinx.Graphics.Shader/Decoders/{OpCodePsetp.cs => OpCodePset.cs} (62%) diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodePsetp.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodePset.cs similarity index 62% rename from Ryujinx.Graphics.Shader/Decoders/OpCodePsetp.cs rename to Ryujinx.Graphics.Shader/Decoders/OpCodePset.cs index 729e3207e..df508442d 100644 --- a/Ryujinx.Graphics.Shader/Decoders/OpCodePsetp.cs +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodePset.cs @@ -2,18 +2,24 @@ using Ryujinx.Graphics.Shader.Instructions; namespace Ryujinx.Graphics.Shader.Decoders { - class OpCodePsetp : OpCodeSet + class OpCodePset : OpCodeSet { public Register Predicate12 { get; } public Register Predicate29 { get; } + public bool InvertA { get; } + public bool InvertB { get; } + public LogicalOperation LogicalOpAB { get; } - public OpCodePsetp(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) + public OpCodePset(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode) { Predicate12 = new Register(opCode.Extract(12, 3), RegisterType.Predicate); Predicate29 = new Register(opCode.Extract(29, 3), RegisterType.Predicate); + InvertA = opCode.Extract(15); + InvertB = opCode.Extract(32); + LogicalOpAB = (LogicalOperation)opCode.Extract(24, 2); } } diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs index a7a7f64e6..d84a58200 100644 --- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs +++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs @@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Shader.Decoders Set("111000100100xx", InstEmit.Bra, typeof(OpCodeBranch)); Set("111000110100xx", InstEmit.Brk, typeof(OpCodeBranchPop)); Set("111000100101xx", InstEmit.Brx, typeof(OpCodeBranchIndir)); - Set("0101000010100x", InstEmit.Csetp, typeof(OpCodePsetp)); + Set("0101000010100x", InstEmit.Csetp, typeof(OpCodePset)); Set("111000110000xx", InstEmit.Exit, typeof(OpCodeExit)); Set("0100110010101x", InstEmit.F2F, typeof(OpCodeFArithCbuf)); Set("0011100x10101x", InstEmit.F2F, typeof(OpCodeFArithImm)); @@ -142,7 +142,8 @@ namespace Ryujinx.Graphics.Shader.Decoders Set("0100110000001x", InstEmit.Popc, typeof(OpCodeAluCbuf)); Set("0011100x00001x", InstEmit.Popc, typeof(OpCodeAluImm)); Set("0101110000001x", InstEmit.Popc, typeof(OpCodeAluReg)); - Set("0101000010010x", InstEmit.Psetp, typeof(OpCodePsetp)); + Set("0101000010001x", InstEmit.Pset, typeof(OpCodePset)); + Set("0101000010010x", InstEmit.Psetp, typeof(OpCodePset)); Set("0100110011110x", InstEmit.R2p, typeof(OpCodeAluCbuf)); Set("0011100x11110x", InstEmit.R2p, typeof(OpCodeAluImm)); Set("0101110011110x", InstEmit.R2p, typeof(OpCodeAluReg)); diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs index 31375e43d..1f6f389d5 100644 --- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs +++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAlu.cs @@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Shader.Instructions public static void Csetp(EmitterContext context) { - OpCodePsetp op = (OpCodePsetp)context.CurrOp; + OpCodePset op = (OpCodePset)context.CurrOp; // TODO: Implement that properly @@ -381,15 +381,38 @@ namespace Ryujinx.Graphics.Shader.Instructions context.Copy(GetDest(context), res); } + public static void Pset(EmitterContext context) + { + OpCodePset op = (OpCodePset)context.CurrOp; + + bool boolFloat = op.RawOpCode.Extract(44); + + Operand srcA = context.BitwiseNot(Register(op.Predicate12), op.InvertA); + Operand srcB = context.BitwiseNot(Register(op.Predicate29), op.InvertB); + Operand srcC = context.BitwiseNot(Register(op.Predicate39), op.InvertP); + + Operand res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB); + + res = GetPredLogicalOp(context, op.LogicalOp, res, srcC); + + Operand dest = GetDest(context); + + if (boolFloat) + { + context.Copy(dest, context.ConditionalSelect(res, ConstF(1), Const(0))); + } + else + { + context.Copy(dest, res); + } + } + public static void Psetp(EmitterContext context) { - OpCodePsetp op = (OpCodePsetp)context.CurrOp; + OpCodePset op = (OpCodePset)context.CurrOp; - bool invertA = op.RawOpCode.Extract(15); - bool invertB = op.RawOpCode.Extract(32); - - Operand srcA = context.BitwiseNot(Register(op.Predicate12), invertA); - Operand srcB = context.BitwiseNot(Register(op.Predicate29), invertB); + Operand srcA = context.BitwiseNot(Register(op.Predicate12), op.InvertA); + Operand srcB = context.BitwiseNot(Register(op.Predicate29), op.InvertB); Operand p0Res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB);