From 03156d0c9a7b3c3f922784845c832ea8299b3c50 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Sun, 18 Mar 2018 19:03:20 -0500
Subject: [PATCH] GPU: Implement macro 0xE1A BindTextureInfoBuffer in HLE.

This macro simply sets the current CB_ADDRESS to the texture buffer address for the input shader stage.
---
 src/video_core/engines/maxwell_3d.cpp | 18 ++++++++++++++++++
 src/video_core/engines/maxwell_3d.h   | 12 +++++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 3a4e88e4e..4fdea0fdc 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -12,6 +12,7 @@ namespace Engines {
 constexpr u32 MacroRegistersStart = 0xE00;
 
 const std::unordered_map<u32, Maxwell3D::MethodInfo> Maxwell3D::method_handlers = {
+    {0xE1A, {"BindTextureInfoBuffer", 1, &Maxwell3D::BindTextureInfoBuffer}},
     {0xE24, {"SetShader", 5, &Maxwell3D::SetShader}},
     {0xE2A, {"BindStorageBuffer", 1, &Maxwell3D::BindStorageBuffer}},
 };
@@ -160,6 +161,23 @@ void Maxwell3D::DrawArrays() {
     LOG_WARNING(HW_GPU, "Game requested a DrawArrays, ignoring");
 }
 
+void Maxwell3D::BindTextureInfoBuffer(const std::vector<u32>& parameters) {
+    /**
+     * Parameters description:
+     * [0] = Shader stage, usually 4 for FragmentShader
+     */
+
+    u32 stage = parameters[0];
+
+    // Perform the same operations as the real macro code.
+    GPUVAddr address = static_cast<GPUVAddr>(regs.tex_info_buffers.address[stage]) << 8;
+    u32 size = regs.tex_info_buffers.size[stage];
+
+    regs.const_buffer.cb_size = size;
+    regs.const_buffer.cb_address_high = address >> 32;
+    regs.const_buffer.cb_address_low = address & 0xFFFFFFFF;
+}
+
 void Maxwell3D::SetShader(const std::vector<u32>& parameters) {
     /**
      * Parameters description:
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 3e97d9045..5d9b0043b 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -178,7 +178,14 @@ public:
                     }
                 } ssbo_info;
 
-                INSERT_PADDING_WORDS(0x11D);
+                INSERT_PADDING_WORDS(0x11);
+
+                struct {
+                    u32 address[MaxShaderStage];
+                    u32 size[MaxShaderStage];
+                } tex_info_buffers;
+
+                INSERT_PADDING_WORDS(0x102);
             };
             std::array<u32, NUM_REGS> reg_array;
         };
@@ -240,6 +247,7 @@ private:
     void DrawArrays();
 
     /// Method call handlers
+    void BindTextureInfoBuffer(const std::vector<u32>& parameters);
     void SetShader(const std::vector<u32>& parameters);
     void BindStorageBuffer(const std::vector<u32>& parameters);
 
@@ -266,6 +274,8 @@ ASSERT_REG_POSITION(const_buffer, 0x8E0);
 ASSERT_REG_POSITION(cb_bind[0], 0x904);
 ASSERT_REG_POSITION(tex_cb_index, 0x982);
 ASSERT_REG_POSITION(ssbo_info, 0xD18);
+ASSERT_REG_POSITION(tex_info_buffers.address[0], 0xD2A);
+ASSERT_REG_POSITION(tex_info_buffers.size[0], 0xD2F);
 
 #undef ASSERT_REG_POSITION