From 59900d7f00b14681acfc7ef5e8d1e18d53664e1c Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Fri, 9 Jul 2021 00:09:07 -0300
Subject: [PATCH] Unscale textureSize when resolution scaling is used (#2441)

* Unscale textureSize when resolution scaling is used

* Fix textureSize on compute

* Flag texture size as needing res scale values too
---
 Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs    |  2 +-
 .../HelperFunctions/TexelFetchScale_cp.glsl   | 10 +++++++++
 .../HelperFunctions/TexelFetchScale_fp.glsl   | 10 +++++++++
 .../Glsl/Instructions/InstGenMemory.cs        | 21 +++++++++++++------
 .../Instructions/InstEmitTexture.cs           |  2 ++
 .../Translation/ShaderConfig.cs               |  3 ++-
 6 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index e9df6bfbd6..031c95a93c 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
         /// <summary>
         /// Version of the codegen (to be changed when codegen or guest format change).
         /// </summary>
-        private const ulong ShaderCodeGenVersion = 2412;
+        private const ulong ShaderCodeGenVersion = 2439;
 
         // Progress reporting helpers
         private volatile int _shaderCount;
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
index 88d18246d3..abc3f42821 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_cp.glsl
@@ -6,4 +6,14 @@
         return inputVec;
     }
     return ivec2(vec2(inputVec) * scale);
+}
+
+int Helper_TextureSizeUnscale(int size, int samplerIndex)
+{
+    float scale = cp_renderScale[samplerIndex];
+    if (scale == 1.0)
+    {
+        return size;
+    }
+    return int(float(size) / scale);
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
index 2e166a4be7..c13e2368ca 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/HelperFunctions/TexelFetchScale_fp.glsl
@@ -13,4 +13,14 @@
     {
         return ivec2(vec2(inputVec) * scale);
     }
+}
+
+int Helper_TextureSizeUnscale(int size, int samplerIndex)
+{
+    float scale = abs(fp_renderScale[1 + samplerIndex]);
+    if (scale == 1.0)
+    {
+        return size;
+    }
+    return int(float(size) / scale);
 }
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
index cb99bdcc43..f6aab74d1b 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
@@ -55,15 +55,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
 
             string ApplyScaling(string vector)
             {
-                int index = context.FindImageDescriptorIndex(texOp);
-
                 if ((context.Config.Stage == ShaderStage.Fragment || context.Config.Stage == ShaderStage.Compute) &&
                     texOp.Inst == Instruction.ImageLoad &&
                     !isBindless &&
                     !isIndexed)
                 {
                     // Image scales start after texture ones.
-                    int scaleIndex = context.Config.GetTextureDescriptors().Length + index;
+                    int scaleIndex = context.Config.GetTextureDescriptors().Length + context.FindImageDescriptorIndex(texOp);
 
                     if (pCount == 3 && isArray)
                     {
@@ -461,12 +459,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
             {
                 if (intCoords)
                 {
-                    int index = context.FindTextureDescriptorIndex(texOp);
-
                     if ((context.Config.Stage == ShaderStage.Fragment || context.Config.Stage == ShaderStage.Compute) &&
                         !isBindless &&
                         !isIndexed)
                     {
+                        int index = context.FindTextureDescriptorIndex(texOp);
+
                         if (pCount == 3 && isArray)
                         {
                             // The array index is not scaled, just x and y.
@@ -608,7 +606,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
             }
             else
             {
-                return $"textureSize({samplerName}, {lodExpr}){GetMask(texOp.Index)}";
+                string texCall = $"textureSize({samplerName}, {lodExpr}){GetMask(texOp.Index)}";
+
+                if ((context.Config.Stage == ShaderStage.Fragment || context.Config.Stage == ShaderStage.Compute) &&
+                    !isBindless &&
+                    !isIndexed)
+                {
+                    int index = context.FindTextureDescriptorIndex(texOp);
+
+                    texCall = "Helper_TextureSizeUnscale(" + texCall + ", " + index + ")";
+                }
+
+                return texCall;
             }
         }
 
diff --git a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
index b59f0d31a5..f1ae89d542 100644
--- a/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
+++ b/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
@@ -1056,6 +1056,8 @@ namespace Ryujinx.Graphics.Shader.Instructions
                 return;
             }
 
+            context.Config.SetUsedFeature(FeatureFlags.IntegerSampling);
+
             TextureProperty property = (TextureProperty)op.RawOpCode.Extract(22, 6);
 
             // TODO: Validate and use property.
diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
index b22eb5f12e..3e7be582a0 100644
--- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
@@ -242,7 +242,8 @@ namespace Ryujinx.Graphics.Shader.Translation
             }
             else
             {
-                SetUsedTextureOrImage(_usedTextures, cbufSlot, handle, type, TextureFormat.Unknown, flags.HasFlag(TextureFlags.IntCoords), false, accurateType);
+                bool intCoords = flags.HasFlag(TextureFlags.IntCoords) || inst == Instruction.TextureSize;
+                SetUsedTextureOrImage(_usedTextures, cbufSlot, handle, type, TextureFormat.Unknown, intCoords, false, accurateType);
             }
         }