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("0011100x1100xx", InstEmit.Iadd3, typeof(OpCodeAluImm));
|
||||
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("0011010x0xxxxx", InstEmit.Imad, typeof(OpCodeAluImm));
|
||||
Set("010110100xxxxx", InstEmit.Imad, typeof(OpCodeAluReg));
|
||||
|
|
|
@ -200,10 +200,27 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
// 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)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
bool signedA = context.CurrOp.RawOpCode.Extract(48);
|
||||
bool signedB = context.CurrOp.RawOpCode.Extract(53);
|
||||
bool high = context.CurrOp.RawOpCode.Extract(54);
|
||||
|
@ -731,19 +748,16 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
}
|
||||
else
|
||||
{
|
||||
Instruction inst;
|
||||
|
||||
switch (cond)
|
||||
var inst = cond switch
|
||||
{
|
||||
case IntegerCondition.Less: inst = Instruction.CompareLessU32; break;
|
||||
case IntegerCondition.Equal: inst = Instruction.CompareEqual; break;
|
||||
case IntegerCondition.LessOrEqual: inst = Instruction.CompareLessOrEqualU32; break;
|
||||
case IntegerCondition.Greater: inst = Instruction.CompareGreaterU32; break;
|
||||
case IntegerCondition.NotEqual: inst = Instruction.CompareNotEqual; break;
|
||||
case IntegerCondition.GreaterOrEqual: inst = Instruction.CompareGreaterOrEqualU32; break;
|
||||
|
||||
default: throw new InvalidOperationException($"Unexpected condition \"{cond}\".");
|
||||
}
|
||||
IntegerCondition.Less => Instruction.CompareLessU32,
|
||||
IntegerCondition.Equal => Instruction.CompareEqual,
|
||||
IntegerCondition.LessOrEqual => Instruction.CompareLessOrEqualU32,
|
||||
IntegerCondition.Greater => Instruction.CompareGreaterU32,
|
||||
IntegerCondition.NotEqual => Instruction.CompareNotEqual,
|
||||
IntegerCondition.GreaterOrEqual => Instruction.CompareGreaterOrEqualU32,
|
||||
_ => throw new InvalidOperationException($"Unexpected condition \"{cond}\".")
|
||||
};
|
||||
|
||||
if (isSigned)
|
||||
{
|
||||
|
|
|
@ -97,8 +97,6 @@ namespace Ryujinx.Graphics.Shader.Instructions
|
|||
|
||||
public static void Sel(EmitterContext context)
|
||||
{
|
||||
OpCodeAlu op = (OpCodeAlu)context.CurrOp;
|
||||
|
||||
Operand pred = GetPredicate39(context);
|
||||
|
||||
Operand srcA = GetSrcA(context);
|
||||
|
|
Reference in a new issue