From e35b9597ef4ecf9d500462ef19510a36a564fd9d Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Fri, 22 Nov 2019 04:34:14 -0300
Subject: [PATCH] gl_shader_decompiler: Normalize image bindings

---
 .../renderer_opengl/gl_rasterizer.cpp         | 29 ++++++-------------
 .../renderer_opengl/gl_shader_decompiler.cpp  | 20 +++++--------
 src/video_core/renderer_opengl/gl_state.h     |  3 +-
 3 files changed, 19 insertions(+), 33 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index de7b7ce934..fbb9bbac18 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -940,12 +940,9 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GLShader::GlobalMemo
 
 void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) {
     MICROPROFILE_SCOPE(OpenGL_Texture);
-    const auto& gpu = system.GPU();
-    const auto& maxwell3d = gpu.Maxwell3D();
-    const auto& entries = shader->GetShaderEntries().samplers;
-
+    const auto& maxwell3d = system.GPU().Maxwell3D();
     u32 binding = device.GetBaseBindings(stage_index).sampler;
-    for (const auto& entry : entries) {
+    for (const auto& entry : shader->GetShaderEntries().samplers) {
         const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage_index);
         const auto texture = GetTextureInfo(maxwell3d, entry, shader_type);
         SetupTexture(binding++, texture, entry);
@@ -955,10 +952,8 @@ void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader&
 void RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) {
     MICROPROFILE_SCOPE(OpenGL_Texture);
     const auto& compute = system.GPU().KeplerCompute();
-    const auto& entries = kernel->GetShaderEntries().samplers;
-
     u32 binding = 0;
-    for (const auto& entry : entries) {
+    for (const auto& entry : kernel->GetShaderEntries().samplers) {
         const auto texture = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute);
         SetupTexture(binding++, texture, entry);
     }
@@ -987,26 +982,20 @@ void RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextu
 
 void RasterizerOpenGL::SetupDrawImages(std::size_t stage_index, const Shader& shader) {
     const auto& maxwell3d = system.GPU().Maxwell3D();
-    const auto& entries = shader->GetShaderEntries().images;
-
-    const auto num_entries = static_cast<u32>(entries.size());
-    for (u32 bindpoint = 0; bindpoint < num_entries; ++bindpoint) {
-        const auto& entry = entries[bindpoint];
+    u32 binding = device.GetBaseBindings(stage_index).image;
+    for (const auto& entry : shader->GetShaderEntries().images) {
         const auto shader_type = static_cast<Tegra::Engines::ShaderType>(stage_index);
         const auto tic = GetTextureInfo(maxwell3d, entry, shader_type).tic;
-        SetupImage(bindpoint, tic, entry);
+        SetupImage(binding++, tic, entry);
     }
 }
 
 void RasterizerOpenGL::SetupComputeImages(const Shader& shader) {
     const auto& compute = system.GPU().KeplerCompute();
-    const auto& entries = shader->GetShaderEntries().images;
-
-    const auto num_entries = static_cast<u32>(entries.size());
-    for (u32 bindpoint = 0; bindpoint < num_entries; ++bindpoint) {
-        const auto& entry = entries[bindpoint];
+    u32 binding = 0;
+    for (const auto& entry : shader->GetShaderEntries().images) {
         const auto tic = GetTextureInfo(compute, entry, Tegra::Engines::ShaderType::Compute).tic;
-        SetupImage(bindpoint, tic, entry);
+        SetupImage(binding++, tic, entry);
     }
 }
 
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 040370c83e..b17c4e7036 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -650,12 +650,10 @@ private:
     }
 
     void DeclareSamplers() {
-        const auto& samplers = ir.GetSamplers();
-        for (const auto& sampler : samplers) {
+        u32 binding = device.GetBaseBindings(stage).sampler;
+        for (const auto& sampler : ir.GetSamplers()) {
             const std::string name = GetSampler(sampler);
-
-            const u32 binding = device.GetBaseBindings(stage).sampler + sampler.GetIndex();
-            const std::string description = fmt::format("layout (binding = {}) uniform", binding);
+            const std::string description = fmt::format("layout (binding = {}) uniform", binding++);
 
             std::string sampler_type = [&]() {
                 if (sampler.IsBuffer()) {
@@ -684,7 +682,7 @@ private:
 
             code.AddLine("{} {} {};", description, sampler_type, name);
         }
-        if (!samplers.empty()) {
+        if (!ir.GetSamplers().empty()) {
             code.AddNewLine();
         }
     }
@@ -724,8 +722,8 @@ private:
     }
 
     void DeclareImages() {
-        const auto& images{ir.GetImages()};
-        for (const auto& image : images) {
+        u32 binding = device.GetBaseBindings(stage).image;
+        for (const auto& image : ir.GetImages()) {
             std::string qualifier = "coherent volatile";
             if (image.IsRead() && !image.IsWritten()) {
                 qualifier += " readonly";
@@ -733,14 +731,12 @@ private:
                 qualifier += " writeonly";
             }
 
-            const u32 binding = device.GetBaseBindings(stage).image + image.GetIndex();
-
             const char* format = image.IsAtomic() ? "r32ui, " : "";
             const char* type_declaration = GetImageTypeDeclaration(image.GetType());
-            code.AddLine("layout ({}binding = {}) {} uniform uimage{} {};", format, binding,
+            code.AddLine("layout ({}binding = {}) {} uniform uimage{} {};", format, binding++,
                          qualifier, type_declaration, GetImage(image));
         }
-        if (!images.empty()) {
+        if (!ir.GetImages().empty()) {
             code.AddNewLine();
         }
     }
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index fd53eb81a5..e53c2c5f24 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -97,9 +97,10 @@ public:
     } logic_op;
 
     static constexpr std::size_t NumSamplers = 32 * 5;
+    static constexpr std::size_t NumImages = 8 * 5;
     std::array<GLuint, NumSamplers> textures = {};
     std::array<GLuint, NumSamplers> samplers = {};
-    std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images = {};
+    std::array<GLuint, NumImages> images = {};
 
     struct {
         GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING