From 21cd4c0c00e4a06e399c93419c8f9eff0e663bfb Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Wed, 22 Nov 2023 20:51:51 -0300
Subject: [PATCH] Extend bindless elimination to see through shuffle (#5958)

* Extend bindless elimination to see through shuffle

* Shader cache version bump
---
 .../Shader/DiskCache/DiskCacheHostStorage.cs          |  2 +-
 .../Translation/Optimizations/BindlessElimination.cs  | 11 ++++++++++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
index 403e039a45..125ab8993f 100644
--- a/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
+++ b/src/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
         private const ushort FileFormatVersionMajor = 1;
         private const ushort FileFormatVersionMinor = 2;
         private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
-        private const uint CodeGenVersion = 5957;
+        private const uint CodeGenVersion = 5958;
 
         private const string SharedTocFileName = "shared.toc";
         private const string SharedDataFileName = "shared.data";
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
index c955f5b5f1..6706053e5a 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -29,7 +29,16 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
 
                 if (texOp.Inst == Instruction.TextureSample || texOp.Inst.IsTextureQuery())
                 {
-                    Operand bindlessHandle = Utils.FindLastOperation(texOp.GetSource(0), block);
+                    Operand bindlessHandle = texOp.GetSource(0);
+
+                    // In some cases the compiler uses a shuffle operation to get the handle,
+                    // for some textureGrad implementations. In those cases, we can skip the shuffle.
+                    if (bindlessHandle.AsgOp is Operation shuffleOp && shuffleOp.Inst == Instruction.Shuffle)
+                    {
+                        bindlessHandle = shuffleOp.GetSource(0);
+                    }
+
+                    bindlessHandle = Utils.FindLastOperation(bindlessHandle, block);
 
                     // Some instructions do not encode an accurate sampler type:
                     // - Most instructions uses the same type for 1D and Buffer.