diff --git a/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs b/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
index 5e7c40f4bc..ca4ff12ad7 100644
--- a/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/InstDecoders.cs
@@ -277,6 +277,16 @@ namespace Ryujinx.Graphics.Shader.Decoders
         S64 = 7,
     }
 
+    enum ISrcDstFmt
+    {
+        U8 = 0,
+        U16 = 1,
+        U32 = 2,
+        S8 = 4,
+        S16 = 5,
+        S32 = 6,
+    }
+
     enum RoundMode2
     {
         Round = 0,
@@ -2720,8 +2730,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
         public bool AbsB => (_opcode & 0x2000000000000) != 0;
         public bool NegB => (_opcode & 0x200000000000) != 0;
         public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
-        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
-        public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+        public ISrcDstFmt IDstFmt => (ISrcDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public ISrcDstFmt ISrcFmt => (ISrcDstFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
     }
 
     struct InstI2iI
@@ -2737,8 +2747,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
         public bool AbsB => (_opcode & 0x2000000000000) != 0;
         public bool NegB => (_opcode & 0x200000000000) != 0;
         public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
-        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
-        public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+        public ISrcDstFmt IDstFmt => (ISrcDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public ISrcDstFmt ISrcFmt => (ISrcDstFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
     }
 
     struct InstI2iC
@@ -2755,8 +2765,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
         public bool AbsB => (_opcode & 0x2000000000000) != 0;
         public bool NegB => (_opcode & 0x200000000000) != 0;
         public ByteSel ByteSel => (ByteSel)((_opcode >> 41) & 0x3);
-        public IDstFmt IDstFmt => (IDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
-        public ISrcFmt SrcFmt => (ISrcFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
+        public ISrcDstFmt IDstFmt => (ISrcDstFmt)((int)((_opcode >> 10) & 0x4) | (int)((_opcode >> 8) & 0x3));
+        public ISrcDstFmt ISrcFmt => (ISrcDstFmt)((int)((_opcode >> 11) & 0x4) | (int)((_opcode >> 10) & 0x3));
     }
 
     struct InstIaddR
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
index 3dda53162f..3fbd0aeb23 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitAluHelper.cs
@@ -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)
         {
             return logicOp switch
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
index 43b07cc2bc..01cdc44540 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitConversion.cs
@@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             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)
@@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             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)
@@ -116,7 +116,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
             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(
@@ -261,8 +261,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
 
         private static void EmitI2I(
             EmitterContext context,
-            ISrcFmt srcType,
-            IDstFmt dstType,
+            ISrcDstFmt srcType,
+            ISrcDstFmt dstType,
             Operand src,
             ByteSel byteSelection,
             int rd,
@@ -270,30 +270,29 @@ namespace Ryujinx.Graphics.Shader.Instructions
             bool negate,
             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.");
                 return;
             }
 
             bool srcIsSignedInt =
-                srcType == ISrcFmt.S8 ||
-                srcType == ISrcFmt.S16 ||
-                srcType == ISrcFmt.S32 ||
-                srcType == ISrcFmt.S64;
+                srcType == ISrcDstFmt.S8 ||
+                srcType == ISrcDstFmt.S16 ||
+                srcType == ISrcDstFmt.S32;
             bool dstIsSignedInt =
-                dstType == IDstFmt.S16 ||
-                dstType == IDstFmt.S32 ||
-                dstType == IDstFmt.S64;
+                dstType == ISrcDstFmt.S8 ||
+                dstType == ISrcDstFmt.S16 ||
+                dstType == ISrcDstFmt.S32;
             bool srcIsSmallInt =
-                srcType == ISrcFmt.U16 ||
-                srcType == ISrcFmt.S16 ||
-                srcType == ISrcFmt.U8 ||
-                srcType == ISrcFmt.S8;
+                srcType == ISrcDstFmt.U16 ||
+                srcType == ISrcDstFmt.S16 ||
+                srcType == ISrcDstFmt.U8 ||
+                srcType == ISrcDstFmt.S8;
 
             if (srcIsSmallInt)
             {
-                int size = srcType == ISrcFmt.U16 || srcType == ISrcFmt.S16 ? 16 : 8;
+                int size = srcType == ISrcDstFmt.U16 || srcType == ISrcDstFmt.S16 ? 16 : 8;
 
                 src = srcIsSignedInt
                     ? context.BitfieldExtractS32(src, Const((int)byteSelection * 8), Const(size))