From 6e386a334b0e61305c7473f2a4676292d0e289bc Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Tue, 5 Jun 2018 22:45:22 -0400
Subject: [PATCH] gl_shader_decompiler: Refactor uniform handling to allow
 different decodings.

---
 src/video_core/engines/shader_bytecode.h      | 16 +++++---
 .../renderer_opengl/gl_shader_decompiler.cpp  | 39 +++++++++----------
 2 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 4eb5073256..7a74771ce7 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -109,11 +109,6 @@ union Sampler {
     u64 value{};
 };
 
-union Uniform {
-    BitField<20, 14, u64> offset;
-    BitField<34, 5, u64> index;
-};
-
 } // namespace Shader
 } // namespace Tegra
 
@@ -354,12 +349,21 @@ union Instruction {
         }
     } bra;
 
+    union {
+        BitField<20, 14, u64> offset;
+        BitField<34, 5, u64> index;
+    } cbuf34;
+
+    union {
+        BitField<20, 16, s64> offset;
+        BitField<36, 5, u64> index;
+    } cbuf36;
+
     BitField<61, 1, u64> is_b_imm;
     BitField<60, 1, u64> is_b_gpr;
     BitField<59, 1, u64> is_c_gpr;
 
     Attribute attribute;
-    Uniform uniform;
     Sampler sampler;
 
     u64 value;
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 7a59ecccf3..94c4858eab 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -20,7 +20,6 @@ using Tegra::Shader::OpCode;
 using Tegra::Shader::Register;
 using Tegra::Shader::Sampler;
 using Tegra::Shader::SubOp;
-using Tegra::Shader::Uniform;
 
 constexpr u32 PROGRAM_END = MAX_PROGRAM_CODE_LENGTH;
 
@@ -365,11 +364,9 @@ public:
     }
 
     /// Generates code representing a uniform (C buffer) register, interpreted as the input type.
-    std::string GetUniform(const Uniform& uniform, GLSLRegister::Type type) {
-        declr_const_buffers[uniform.index].MarkAsUsed(static_cast<unsigned>(uniform.index),
-                                                      static_cast<unsigned>(uniform.offset), stage);
-        std::string value =
-            'c' + std::to_string(uniform.index) + '[' + std::to_string(uniform.offset) + ']';
+    std::string GetUniform(u64 index, u64 offset, GLSLRegister::Type type) {
+        declr_const_buffers[index].MarkAsUsed(index, offset, stage);
+        std::string value = 'c' + std::to_string(index) + '[' + std::to_string(offset) + ']';
 
         if (type == GLSLRegister::Type::Float) {
             return value;
@@ -380,12 +377,6 @@ public:
         }
     }
 
-    /// Generates code representing a uniform (C buffer) register, interpreted as the type of the
-    /// destination register.
-    std::string GetUniform(const Uniform& uniform, const Register& dest_reg) {
-        return GetUniform(uniform, regs[dest_reg].GetActiveType());
-    }
-
     /// Add declarations for registers
     void GenerateDeclarations() {
         for (const auto& reg : regs) {
@@ -747,7 +738,8 @@ private:
                 if (instr.is_b_gpr) {
                     op_b += regs.GetRegisterAsFloat(instr.gpr20);
                 } else {
-                    op_b += regs.GetUniform(instr.uniform, instr.gpr0);
+                    op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                            GLSLRegister::Type::Float);
                 }
             }
 
@@ -904,7 +896,8 @@ private:
                 if (instr.is_b_gpr) {
                     op_b += regs.GetRegisterAsInteger(instr.gpr20);
                 } else {
-                    op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Integer);
+                    op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                            GLSLRegister::Type::Integer);
                 }
             }
 
@@ -936,7 +929,8 @@ private:
                 if (instr.is_b_gpr) {
                     op_b += regs.GetRegisterAsInteger(instr.gpr20);
                 } else {
-                    op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Integer);
+                    op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                            GLSLRegister::Type::Integer);
                 }
             }
 
@@ -953,7 +947,8 @@ private:
 
             switch (opcode->GetId()) {
             case OpCode::Id::FFMA_CR: {
-                op_b += regs.GetUniform(instr.uniform, instr.gpr0);
+                op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                        GLSLRegister::Type::Float);
                 op_c += regs.GetRegisterAsFloat(instr.gpr39);
                 break;
             }
@@ -964,7 +959,8 @@ private:
             }
             case OpCode::Id::FFMA_RC: {
                 op_b += regs.GetRegisterAsFloat(instr.gpr39);
-                op_c += regs.GetUniform(instr.uniform, instr.gpr0);
+                op_c += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                        GLSLRegister::Type::Float);
                 break;
             }
             case OpCode::Id::FFMA_IMM: {
@@ -1175,7 +1171,8 @@ private:
                 if (instr.is_b_gpr) {
                     op_b += regs.GetRegisterAsFloat(instr.gpr20);
                 } else {
-                    op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Float);
+                    op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                            GLSLRegister::Type::Float);
                 }
             }
 
@@ -1216,7 +1213,8 @@ private:
             if (instr.is_b_gpr) {
                 op_b += regs.GetRegisterAsInteger(instr.gpr20, 0, instr.isetp.is_signed);
             } else {
-                op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Integer);
+                op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                        GLSLRegister::Type::Integer);
             }
 
             using Tegra::Shader::Pred;
@@ -1262,7 +1260,8 @@ private:
                 if (instr.is_b_gpr) {
                     op_b += regs.GetRegisterAsFloat(instr.gpr20);
                 } else {
-                    op_b += regs.GetUniform(instr.uniform, GLSLRegister::Type::Float);
+                    op_b += regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
+                                            GLSLRegister::Type::Float);
                 }
             }