Implement ICMP shader instruction (#1010)
This commit is contained in:
parent
9a208c4fb5
commit
6edc929894
3 changed files with 32 additions and 16 deletions
|
@ -120,6 +120,10 @@ namespace Ryujinx.Graphics.Shader.Decoders
|
||||||
Set("010011001100xx", InstEmit.Iadd3, typeof(OpCodeAluCbuf));
|
Set("010011001100xx", InstEmit.Iadd3, typeof(OpCodeAluCbuf));
|
||||||
Set("0011100x1100xx", InstEmit.Iadd3, typeof(OpCodeAluImm));
|
Set("0011100x1100xx", InstEmit.Iadd3, typeof(OpCodeAluImm));
|
||||||
Set("010111001100xx", InstEmit.Iadd3, typeof(OpCodeAluReg));
|
Set("010111001100xx", InstEmit.Iadd3, typeof(OpCodeAluReg));
|
||||||
|
Set("010010110100xx", InstEmit.Icmp, typeof(OpCodeAluCbuf));
|
||||||
|
Set("0011011x0100xx", InstEmit.Icmp, typeof(OpCodeAluImm));
|
||||||
|
Set("010110110100xx", InstEmit.Icmp, typeof(OpCodeAluReg));
|
||||||
|
Set("010100110100xx", InstEmit.Icmp, typeof(OpCodeAluRegCbuf));
|
||||||
Set("010010100xxxxx", InstEmit.Imad, typeof(OpCodeAluCbuf));
|
Set("010010100xxxxx", InstEmit.Imad, typeof(OpCodeAluCbuf));
|
||||||
Set("0011010x0xxxxx", InstEmit.Imad, typeof(OpCodeAluImm));
|
Set("0011010x0xxxxx", InstEmit.Imad, typeof(OpCodeAluImm));
|
||||||
Set("010110100xxxxx", InstEmit.Imad, typeof(OpCodeAluReg));
|
Set("010110100xxxxx", InstEmit.Imad, typeof(OpCodeAluReg));
|
||||||
|
|
|
@ -200,10 +200,27 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
// TODO: CC, X, corner cases
|
// TODO: CC, X, corner cases
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Icmp(EmitterContext context)
|
||||||
|
{
|
||||||
|
OpCode op = context.CurrOp;
|
||||||
|
|
||||||
|
bool isSigned = op.RawOpCode.Extract(48);
|
||||||
|
|
||||||
|
IntegerCondition cmpOp = (IntegerCondition)op.RawOpCode.Extract(49, 3);
|
||||||
|
|
||||||
|
Operand srcA = GetSrcA(context);
|
||||||
|
Operand srcB = GetSrcB(context);
|
||||||
|
Operand srcC = GetSrcC(context);
|
||||||
|
|
||||||
|
Operand cmpRes = GetIntComparison(context, cmpOp, srcC, Const(0), isSigned);
|
||||||
|
|
||||||
|
Operand res = context.ConditionalSelect(cmpRes, srcA, srcB);
|
||||||
|
|
||||||
|
context.Copy(GetDest(context), res);
|
||||||
|
}
|
||||||
|
|
||||||
public static void Imad(EmitterContext context)
|
public static void Imad(EmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
|
||||||
|
|
||||||
bool signedA = context.CurrOp.RawOpCode.Extract(48);
|
bool signedA = context.CurrOp.RawOpCode.Extract(48);
|
||||||
bool signedB = context.CurrOp.RawOpCode.Extract(53);
|
bool signedB = context.CurrOp.RawOpCode.Extract(53);
|
||||||
bool high = context.CurrOp.RawOpCode.Extract(54);
|
bool high = context.CurrOp.RawOpCode.Extract(54);
|
||||||
|
@ -731,19 +748,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Instruction inst;
|
var inst = cond switch
|
||||||
|
|
||||||
switch (cond)
|
|
||||||
{
|
{
|
||||||
case IntegerCondition.Less: inst = Instruction.CompareLessU32; break;
|
IntegerCondition.Less => Instruction.CompareLessU32,
|
||||||
case IntegerCondition.Equal: inst = Instruction.CompareEqual; break;
|
IntegerCondition.Equal => Instruction.CompareEqual,
|
||||||
case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqualU32; break;
|
IntegerCondition.LessOrEqual => Instruction.CompareLessOrEqualU32,
|
||||||
case IntegerCondition.Greater: inst = Instruction.CompareGreaterU32; break;
|
IntegerCondition.Greater => Instruction.CompareGreaterU32,
|
||||||
case IntegerCondition.NotEqual: inst = Instruction.CompareNotEqual; break;
|
IntegerCondition.NotEqual => Instruction.CompareNotEqual,
|
||||||
case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqualU32; break;
|
IntegerCondition.GreaterOrEqual => Instruction.CompareGreaterOrEqualU32,
|
||||||
|
_ => throw new InvalidOperationException($"Unexpected condition \"{cond}\".")
|
||||||
default: throw new InvalidOperationException($"Unexpected condition \"{cond}\".");
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if (isSigned)
|
if (isSigned)
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,8 +97,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
||||||
|
|
||||||
public static void Sel(EmitterContext context)
|
public static void Sel(EmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
|
||||||
|
|
||||||
Operand pred = GetPredicate39(context);
|
Operand pred = GetPredicate39(context);
|
||||||
|
|
||||||
Operand srcA = GetSrcA(context);
|
Operand srcA = GetSrcA(context);
|
||||||
|
|
Reference in a new issue