Add missing U8/S8 types from shader I2I instruction (#2740)

* Add missing U8/S8 types from shader I2I instruction

* Better names

* Fix dstIsSignedInt
This commit is contained in:
gdkchan 2021-10-17 17:48:36 -03:00 committed by GitHub
parent 25fd4ef10e
commit 7603dbe3c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 24 deletions

View file

@ -277,6 +277,16 @@ namespace Ryujinx.Graphics.Shader.Decoders
S64 = 7, S64 = 7,
} }
enum ISrcDstFmt
{
U8 = 0,
U16 = 1,
U32 = 2,
S8 = 4,
S16 = 5,
S32 = 6,
}
enum RoundMode2 enum RoundMode2
{ {
Round = 0, Round = 0,
@ -2720,8 +2730,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool AbsB => (_opcode & 0x2000000000000) != 0; public bool AbsB => (_opcode & 0x2000000000000) != 0;
public bool NegB => (_opcode & 0x200000000000) != 0; public bool NegB => (_opcode & 0x200000000000) != 0;
public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3); public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3)); public ISrcDstFmt IDstFmt => (ISrcDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3)); public ISrcDstFmt ISrcFmt => (ISrcDstFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
} }
struct InstI2iI struct InstI2iI
@ -2737,8 +2747,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool AbsB => (_opcode & 0x2000000000000) != 0; public bool AbsB => (_opcode & 0x2000000000000) != 0;
public bool NegB => (_opcode & 0x200000000000) != 0; public bool NegB => (_opcode & 0x200000000000) != 0;
public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3); public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3)); public ISrcDstFmt IDstFmt => (ISrcDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3)); public ISrcDstFmt ISrcFmt => (ISrcDstFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
} }
struct InstI2iC struct InstI2iC
@ -2755,8 +2765,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
public bool AbsB => (_opcode & 0x2000000000000) != 0; public bool AbsB => (_opcode & 0x2000000000000) != 0;
public bool NegB => (_opcode & 0x200000000000) != 0; public bool NegB => (_opcode & 0x200000000000) != 0;
public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3); public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3)); public ISrcDstFmt IDstFmt => (ISrcDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3)); public ISrcDstFmt ISrcFmt => (ISrcDstFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
} }
struct InstIaddR struct InstIaddR

View file

@ -34,6 +34,34 @@ namespace Ryujinx.Graphics.Shader.Instructions
}; };
} }
public static long GetIntMin(ISrcDstFmt type)
{
return type switch
{
ISrcDstFmt.U8 => byte.MinValue,
ISrcDstFmt.S8 => sbyte.MinValue,
ISrcDstFmt.U16 => ushort.MinValue,
ISrcDstFmt.S16 => short.MinValue,
ISrcDstFmt.U32 => uint.MinValue,
ISrcDstFmt.S32 => int.MinValue,
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
};
}
public static long GetIntMax(ISrcDstFmt type)
{
return type switch
{
ISrcDstFmt.U8 => byte.MaxValue,
ISrcDstFmt.S8 => sbyte.MaxValue,
ISrcDstFmt.U16 => ushort.MaxValue,
ISrcDstFmt.S16 => short.MaxValue,
ISrcDstFmt.U32 => uint.MaxValue,
ISrcDstFmt.S32 => int.MaxValue,
_ => throw new ArgumentException($"The type \"{type}\" is not a supported integer type.")
};
}
public static Operand GetPredLogicalOp(EmitterContext context, BoolOp logicOp, Operand input, Operand pred) public static Operand GetPredLogicalOp(EmitterContext context, BoolOp logicOp, Operand input, Operand pred)
{ {
return logicOp switch return logicOp switch

View file

@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
var src = GetSrcReg(context, op.SrcB); var src = GetSrcReg(context, op.SrcB);
EmitI2I(context, op.SrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat); EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat);
} }
public static void I2iI(EmitterContext context) public static void I2iI(EmitterContext context)
@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
var src = GetSrcImm(context, Imm20ToSInt(op.Imm20)); var src = GetSrcImm(context, Imm20ToSInt(op.Imm20));
EmitI2I(context, op.SrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat); EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat);
} }
public static void I2iC(EmitterContext context) public static void I2iC(EmitterContext context)
@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
var src = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset); var src = GetSrcCbuf(context, op.CbufSlot, op.CbufOffset);
EmitI2I(context, op.SrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat); EmitI2I(context, op.ISrcFmt, op.IDstFmt, src, op.ByteSel, op.Dest, op.AbsB, op.NegB, op.Sat);
} }
private static void EmitF2F( private static void EmitF2F(
@ -261,8 +261,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
private static void EmitI2I( private static void EmitI2I(
EmitterContext context, EmitterContext context,
ISrcFmt srcType, ISrcDstFmt srcType,
IDstFmt dstType, ISrcDstFmt dstType,
Operand src, Operand src,
ByteSel byteSelection, ByteSel byteSelection,
int rd, int rd,
@ -270,30 +270,29 @@ namespace Ryujinx.Graphics.Shader.Instructions
bool negate, bool negate,
bool saturate) bool saturate)
{ {
if (srcType == ISrcFmt.U64 || dstType == IDstFmt.U64) if ((srcType & ~ISrcDstFmt.S8) > ISrcDstFmt.U32 || (dstType & ~ISrcDstFmt.S8) > ISrcDstFmt.U32)
{ {
context.Config.GpuAccessor.Log("Invalid I2I encoding."); context.Config.GpuAccessor.Log("Invalid I2I encoding.");
return; return;
} }
bool srcIsSignedInt = bool srcIsSignedInt =
srcType == ISrcFmt.S8 || srcType == ISrcDstFmt.S8 ||
srcType == ISrcFmt.S16 || srcType == ISrcDstFmt.S16 ||
srcType == ISrcFmt.S32 || srcType == ISrcDstFmt.S32;
srcType == ISrcFmt.S64;
bool dstIsSignedInt = bool dstIsSignedInt =
dstType == IDstFmt.S16 || dstType == ISrcDstFmt.S8 ||
dstType == IDstFmt.S32 || dstType == ISrcDstFmt.S16 ||
dstType == IDstFmt.S64; dstType == ISrcDstFmt.S32;
bool srcIsSmallInt = bool srcIsSmallInt =
srcType == ISrcFmt.U16 || srcType == ISrcDstFmt.U16 ||
srcType == ISrcFmt.S16 || srcType == ISrcDstFmt.S16 ||
srcType == ISrcFmt.U8 || srcType == ISrcDstFmt.U8 ||
srcType == ISrcFmt.S8; srcType == ISrcDstFmt.S8;
if (srcIsSmallInt) if (srcIsSmallInt)
{ {
int size = srcType == ISrcFmt.U16 || srcType == ISrcFmt.S16 ? 16 : 8; int size = srcType == ISrcDstFmt.U16 || srcType == ISrcDstFmt.S16 ? 16 : 8;
src = srcIsSignedInt src = srcIsSignedInt
? context.BitfieldExtractS32(src, Const((int)byteSelection * 8), Const(size)) ? context.BitfieldExtractS32(src, Const((int)byteSelection * 8), Const(size))