diff --git a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
index dcb6b1f6a9..be93f1375a 100644
--- a/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
+++ b/Ryujinx.Graphics.Shader/Decoders/OpCodeTable.cs
@@ -231,6 +231,8 @@ namespace Ryujinx.Graphics.Shader.Decoders
             Set("11011101xx111x", InstEmit.TldB,    typeof(OpCodeTld));
             Set("110010xxxx111x", InstEmit.Tld4,    typeof(OpCodeTld4));
             Set("1101111011111x", InstEmit.Tld4,    typeof(OpCodeTld4B));
+            Set("11011111011000", InstEmit.TmmlB,   typeof(OpCodeTexture));
+            Set("11011111010110", InstEmit.Tmml,    typeof(OpCodeTexture));
             Set("110111100x1110", InstEmit.Txd,     typeof(OpCodeTxd));
             Set("1101111101001x", InstEmit.Txq,     typeof(OpCodeTex));
             Set("1101111101010x", InstEmit.TxqB,    typeof(OpCodeTex));
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
index 7f7a48a667..af5122bedc 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
@@ -716,6 +716,130 @@ namespace Ryujinx.Graphics.Shader.Instructions
             }
         }
 
+        public static void TmmlB(EmitterContext context)
+        {
+            EmitTextureMipMapLevel(context, true);
+        }
+
+        public static void Tmml(EmitterContext context)
+        {
+            EmitTextureMipMapLevel(context, false);
+        }
+
+        private static void EmitTextureMipMapLevel(EmitterContext context, bool isBindless)
+        {
+            OpCodeTexture op = (OpCodeTexture)context.CurrOp;
+
+            if (op.Rd.IsRZ)
+            {
+                return;
+            }
+
+            int raIndex = op.Ra.Index;
+            int rbIndex = op.Rb.Index;
+
+            Operand Ra()
+            {
+                if (raIndex > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(raIndex++, RegisterType.Gpr));
+            }
+
+            Operand Rb()
+            {
+                if (rbIndex > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return context.Copy(Register(rbIndex++, RegisterType.Gpr));
+            }
+
+            TextureFlags flags = TextureFlags.None;
+
+            List<Operand> sourcesList = new List<Operand>();
+
+            if (isBindless)
+            {
+                sourcesList.Add(Rb());
+
+                flags |= TextureFlags.Bindless;
+            }
+
+            SamplerType type = ConvertSamplerType(op.Dimensions);
+
+            int coordsCount = type.GetDimensions();
+
+            Operand arrayIndex = op.IsArray ? Ra() : null;
+
+            for (int index = 0; index < coordsCount; index++)
+            {
+                sourcesList.Add(Ra());
+            }
+
+            if (op.IsArray)
+            {
+                sourcesList.Add(arrayIndex);
+
+                type |= SamplerType.Array;
+            }
+
+            Operand[] sources = sourcesList.ToArray();
+
+            int rdIndex = op.Rd.Index;
+
+            Operand GetDest()
+            {
+                if (rdIndex > RegisterConsts.RegisterZeroIndex)
+                {
+                    return Const(0);
+                }
+
+                return Register(rdIndex++, RegisterType.Gpr);
+            }
+
+            int handle = !isBindless ? op.Immediate : 0;
+
+            for (int compMask = op.ComponentMask, compIndex = 0; compMask != 0; compMask >>= 1, compIndex++)
+            {
+                if ((compMask & 1) != 0)
+                {
+                    Operand dest = GetDest();
+
+                    // Components z and w aren't standard, we return 0 in this case and add a comment.
+                    if (compIndex >= 2)
+                    {
+                        context.Add(new CommentNode("Unsupported component z or w found"));
+                        context.Copy(dest, Const(0));
+                    }
+                    else
+                    {
+                        Operand tempDest = Local();
+
+                        TextureOperation operation = new TextureOperation(
+                            Instruction.Lod,
+                            type,
+                            flags,
+                            handle,
+                            compIndex,
+                            tempDest,
+                            sources);
+
+                        context.Add(operation);
+
+                        tempDest = context.FPMultiply(tempDest, ConstF(256.0f));
+
+                        Operand finalValue = context.FPConvertToS32(tempDest);
+
+                        context.Copy(dest, finalValue);
+                    }
+                }
+            }
+        }
+
         public static void Txd(EmitterContext context)
         {
             OpCodeTxd op = (OpCodeTxd)context.CurrOp;