From 037ea431ceb93e93274fdcf9fb724819639d04fd Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow <fsahmkow27@gmail.com>
Date: Sun, 5 Jan 2020 18:36:21 -0400
Subject: Shader_IR: deduce size of indexed samplers

---
 src/video_core/shader/decode.cpp | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

(limited to 'src/video_core/shader/decode.cpp')

diff --git a/src/video_core/shader/decode.cpp b/src/video_core/shader/decode.cpp
index 507614d59d..dd2f68a3e9 100644
--- a/src/video_core/shader/decode.cpp
+++ b/src/video_core/shader/decode.cpp
@@ -56,6 +56,29 @@ void DeduceTextureHandlerSize(VideoCore::GuestDriverProfile* gpu_driver,
     }
 }
 
+std::optional<u32> TryDeduceSamplerSize(Sampler& sampler_to_deduce,
+                                        VideoCore::GuestDriverProfile* gpu_driver,
+                                        std::list<Sampler>& used_samplers) {
+    if (gpu_driver == nullptr) {
+        LOG_CRITICAL(HW_GPU, "GPU Driver profile has not been created yet");
+        return std::nullopt;
+    }
+    const u32 base_offset = sampler_to_deduce.GetOffset();
+    u32 max_offset{UINT_MAX};
+    for (const auto& sampler : used_samplers) {
+        if (sampler.IsBindless()) {
+            continue;
+        }
+        if (sampler.GetOffset() > base_offset) {
+            max_offset = std::min(sampler.GetOffset(), max_offset);
+        }
+    }
+    if (max_offset == UINT_MAX) {
+        return std::nullopt;
+    }
+    return ((max_offset - base_offset) * 4) / gpu_driver->GetTextureHandlerSize();
+}
+
 } // Anonymous namespace
 
 class ASTDecoder {
@@ -342,6 +365,19 @@ void ShaderIR::PostDecode() {
     // Deduce texture handler size if needed
     auto gpu_driver = locker.AccessGuestDriverProfile();
     DeduceTextureHandlerSize(gpu_driver, used_samplers);
+    // Deduce Indexed Samplers
+    if (uses_indexed_samplers) {
+        for (auto& sampler : used_samplers) {
+            if (sampler.IsIndexed()) {
+                auto size = TryDeduceSamplerSize(sampler, gpu_driver, used_samplers);
+                if (size) {
+                    sampler.SetSize(*size);
+                } else {
+                    sampler.SetSize(1);
+                }
+            }
+        }
+    }
 }
 
 } // namespace VideoCommon::Shader
-- 
cgit v1.2.3-70-g09d2