forked from Mirror/Ryujinx
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:
parent
25fd4ef10e
commit
7603dbe3c8
3 changed files with 61 additions and 24 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
Loading…
Reference in a new issue