forked from Mirror/Ryujinx
Add PSET shader instruction
This commit is contained in:
parent
73e68edd09
commit
e0c95b18eb
3 changed files with 41 additions and 11 deletions
|
@ -2,18 +2,24 @@ using Ryujinx.Graphics.Shader.Instructions;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Shader.Decoders
|
namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
{
|
{
|
||||||
class OpCodePsetp : OpCodeSet
|
class OpCodePset : OpCodeSet
|
||||||
{
|
{
|
||||||
public Register Predicate12 { get; }
|
public Register Predicate12 { get; }
|
||||||
public Register Predicate29 { get; }
|
public Register Predicate29 { get; }
|
||||||
|
|
||||||
|
public bool InvertA { get; }
|
||||||
|
public bool InvertB { get; }
|
||||||
|
|
||||||
public LogicalOperation LogicalOpAB { 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);
|
Predicate12 = new Register(opCode.Extract(12, 3), RegisterType.Predicate);
|
||||||
Predicate29 = new Register(opCode.Extract(29, 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);
|
LogicalOpAB = (LogicalOperation)opCode.Extract(24, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
Set("111000100100xx", InstEmit.Bra, typeof(OpCodeBranch));
|
Set("111000100100xx", InstEmit.Bra, typeof(OpCodeBranch));
|
||||||
Set("111000110100xx", InstEmit.Brk, typeof(OpCodeBranchPop));
|
Set("111000110100xx", InstEmit.Brk, typeof(OpCodeBranchPop));
|
||||||
Set("111000100101xx", InstEmit.Brx, typeof(OpCodeBranchIndir));
|
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("111000110000xx", InstEmit.Exit, typeof(OpCodeExit));
|
||||||
Set("0100110010101x", InstEmit.F2F, typeof(OpCodeFArithCbuf));
|
Set("0100110010101x", InstEmit.F2F, typeof(OpCodeFArithCbuf));
|
||||||
Set("0011100x10101x", InstEmit.F2F, typeof(OpCodeFArithImm));
|
Set("0011100x10101x", InstEmit.F2F, typeof(OpCodeFArithImm));
|
||||||
|
@ -142,7 +142,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
Set("0100110000001x", InstEmit.Popc, typeof(OpCodeAluCbuf));
|
Set("0100110000001x", InstEmit.Popc, typeof(OpCodeAluCbuf));
|
||||||
Set("0011100x00001x", InstEmit.Popc, typeof(OpCodeAluImm));
|
Set("0011100x00001x", InstEmit.Popc, typeof(OpCodeAluImm));
|
||||||
Set("0101110000001x", InstEmit.Popc, typeof(OpCodeAluReg));
|
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("0100110011110x", InstEmit.R2p, typeof(OpCodeAluCbuf));
|
||||||
Set("0011100x11110x", InstEmit.R2p, typeof(OpCodeAluImm));
|
Set("0011100x11110x", InstEmit.R2p, typeof(OpCodeAluImm));
|
||||||
Set("0101110011110x", InstEmit.R2p, typeof(OpCodeAluReg));
|
Set("0101110011110x", InstEmit.R2p, typeof(OpCodeAluReg));
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
|
|
||||||
public static void Csetp(EmitterContext context)
|
public static void Csetp(EmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodePsetp op = (OpCodePsetp)context.CurrOp;
|
OpCodePset op = (OpCodePset)context.CurrOp;
|
||||||
|
|
||||||
// TODO: Implement that properly
|
// TODO: Implement that properly
|
||||||
|
|
||||||
|
@ -381,15 +381,38 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
context.Copy(GetDest(context), res);
|
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)
|
public static void Psetp(EmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodePsetp op = (OpCodePsetp)context.CurrOp;
|
OpCodePset op = (OpCodePset)context.CurrOp;
|
||||||
|
|
||||||
bool invertA = op.RawOpCode.Extract(15);
|
Operand srcA = context.BitwiseNot(Register(op.Predicate12), op.InvertA);
|
||||||
bool invertB = op.RawOpCode.Extract(32);
|
Operand srcB = context.BitwiseNot(Register(op.Predicate29), op.InvertB);
|
||||||
|
|
||||||
Operand srcA = context.BitwiseNot(Register(op.Predicate12), invertA);
|
|
||||||
Operand srcB = context.BitwiseNot(Register(op.Predicate29), invertB);
|
|
||||||
|
|
||||||
Operand p0Res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB);
|
Operand p0Res = GetPredLogicalOp(context, op.LogicalOpAB, srcA, srcB);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue