From f7c7f422c6995a31c1a16c0865bbe13bb38469a3 Mon Sep 17 00:00:00 2001
From: Yuri Kunde Schlesner <yuriks@yuriks.net>
Date: Sat, 28 Jan 2017 13:03:13 -0800
Subject: [PATCH] VideoCore: Split shader regs from Regs struct

---
 src/video_core/CMakeLists.txt                |   1 +
 src/video_core/debug_utils/debug_utils.cpp   |   2 +-
 src/video_core/debug_utils/debug_utils.h     |   2 +-
 src/video_core/pica.h                        |  97 +----------------
 src/video_core/regs_shader.h                 | 104 +++++++++++++++++++
 src/video_core/shader/shader.cpp             |   4 +-
 src/video_core/shader/shader.h               |   4 +-
 src/video_core/shader/shader_interpreter.cpp |   2 +-
 src/video_core/shader/shader_interpreter.h   |   2 +-
 9 files changed, 116 insertions(+), 102 deletions(-)
 create mode 100644 src/video_core/regs_shader.h

diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index c8d2675ae..2b0bf0960 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -36,6 +36,7 @@ set(HEADERS
             regs_lighting.h
             regs_pipeline.h
             regs_rasterizer.h
+            regs_shader.h
             regs_texturing.h
             renderer_base.h
             renderer_opengl/gl_rasterizer.h
diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp
index 81cd35cd9..ec8a9ee4a 100644
--- a/src/video_core/debug_utils/debug_utils.cpp
+++ b/src/video_core/debug_utils/debug_utils.cpp
@@ -88,7 +88,7 @@ std::shared_ptr<DebugContext> g_debug_context; // TODO: Get rid of this global
 
 namespace DebugUtils {
 
-void DumpShader(const std::string& filename, const Regs::ShaderConfig& config,
+void DumpShader(const std::string& filename, const ShaderRegs& config,
                 const Shader::ShaderSetup& setup,
                 const RasterizerRegs::VSOutputAttributes* output_attributes) {
     struct StuffToWrite {
diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h
index e58b76d41..44d5af462 100644
--- a/src/video_core/debug_utils/debug_utils.h
+++ b/src/video_core/debug_utils/debug_utils.h
@@ -182,7 +182,7 @@ namespace DebugUtils {
 #define PICA_DUMP_TEXTURES 0
 #define PICA_LOG_TEV 0
 
-void DumpShader(const std::string& filename, const Regs::ShaderConfig& config,
+void DumpShader(const std::string& filename, const ShaderRegs& config,
                 const Shader::ShaderSetup& setup,
                 const RasterizerRegs::VSOutputAttributes* output_attributes);
 
diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 765fa5dd4..099dc84f0 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -22,6 +22,7 @@
 #include "video_core/regs_lighting.h"
 #include "video_core/regs_pipeline.h"
 #include "video_core/regs_rasterizer.h"
+#include "video_core/regs_shader.h"
 #include "video_core/regs_texturing.h"
 
 namespace Pica {
@@ -57,97 +58,8 @@ struct Regs {
     FramebufferRegs framebuffer;
     LightingRegs lighting;
     PipelineRegs pipeline;
-
-    struct ShaderConfig {
-        BitField<0, 16, u32> bool_uniforms;
-
-        union {
-            BitField<0, 8, u32> x;
-            BitField<8, 8, u32> y;
-            BitField<16, 8, u32> z;
-            BitField<24, 8, u32> w;
-        } int_uniforms[4];
-
-        INSERT_PADDING_WORDS(0x4);
-
-        union {
-            // Number of input attributes to shader unit - 1
-            BitField<0, 4, u32> max_input_attribute_index;
-        };
-
-        // Offset to shader program entry point (in words)
-        BitField<0, 16, u32> main_offset;
-
-        /// Maps input attributes to registers. 4-bits per attribute, specifying a register index
-        u32 input_attribute_to_register_map_low;
-        u32 input_attribute_to_register_map_high;
-
-        unsigned int GetRegisterForAttribute(unsigned int attribute_index) const {
-            u64 map = ((u64)input_attribute_to_register_map_high << 32) |
-                      (u64)input_attribute_to_register_map_low;
-            return (map >> (attribute_index * 4)) & 0b1111;
-        }
-
-        BitField<0, 16, u32> output_mask;
-
-        // 0x28E, CODETRANSFER_END
-        INSERT_PADDING_WORDS(0x2);
-
-        struct {
-            enum Format : u32 {
-                FLOAT24 = 0,
-                FLOAT32 = 1,
-            };
-
-            bool IsFloat32() const {
-                return format == FLOAT32;
-            }
-
-            union {
-                // Index of the next uniform to write to
-                // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid
-                // indices
-                // TODO: Maybe the uppermost index is for the geometry shader? Investigate!
-                BitField<0, 7, u32> index;
-
-                BitField<31, 1, Format> format;
-            };
-
-            // Writing to these registers sets the current uniform.
-            u32 set_value[8];
-
-        } uniform_setup;
-
-        INSERT_PADDING_WORDS(0x2);
-
-        struct {
-            // Offset of the next instruction to write code to.
-            // Incremented with each instruction write.
-            u32 offset;
-
-            // Writing to these registers sets the "current" word in the shader program.
-            u32 set_word[8];
-        } program;
-
-        INSERT_PADDING_WORDS(0x1);
-
-        // This register group is used to load an internal table of swizzling patterns,
-        // which are indexed by each shader instruction to specify vector component swizzling.
-        struct {
-            // Offset of the next swizzle pattern to write code to.
-            // Incremented with each instruction write.
-            u32 offset;
-
-            // Writing to these registers sets the current swizzle pattern in the table.
-            u32 set_word[8];
-        } swizzle_patterns;
-
-        INSERT_PADDING_WORDS(0x2);
-    };
-
-    ShaderConfig gs;
-    ShaderConfig vs;
-
+    ShaderRegs gs;
+    ShaderRegs vs;
     INSERT_PADDING_WORDS(0x20);
 
     // Map register indices to names readable by humans
@@ -247,9 +159,6 @@ ASSERT_REG_POSITION(vs, 0x2b0);
 #undef ASSERT_REG_POSITION
 #endif // !defined(_MSC_VER)
 
-static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32),
-              "ShaderConfig structure has incorrect size");
-
 // The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value
 // anyway.
 static_assert(sizeof(Regs) <= 0x300 * sizeof(u32),
diff --git a/src/video_core/regs_shader.h b/src/video_core/regs_shader.h
new file mode 100644
index 000000000..ddb1ee451
--- /dev/null
+++ b/src/video_core/regs_shader.h
@@ -0,0 +1,104 @@
+// Copyright 2017 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+
+#include "common/bit_field.h"
+#include "common/common_funcs.h"
+#include "common/common_types.h"
+
+namespace Pica {
+
+struct ShaderRegs {
+    BitField<0, 16, u32> bool_uniforms;
+
+    union {
+        BitField<0, 8, u32> x;
+        BitField<8, 8, u32> y;
+        BitField<16, 8, u32> z;
+        BitField<24, 8, u32> w;
+    } int_uniforms[4];
+
+    INSERT_PADDING_WORDS(0x4);
+
+    union {
+        // Number of input attributes to shader unit - 1
+        BitField<0, 4, u32> max_input_attribute_index;
+    };
+
+    // Offset to shader program entry point (in words)
+    BitField<0, 16, u32> main_offset;
+
+    /// Maps input attributes to registers. 4-bits per attribute, specifying a register index
+    u32 input_attribute_to_register_map_low;
+    u32 input_attribute_to_register_map_high;
+
+    unsigned int GetRegisterForAttribute(unsigned int attribute_index) const {
+        u64 map = ((u64)input_attribute_to_register_map_high << 32) |
+                  (u64)input_attribute_to_register_map_low;
+        return (map >> (attribute_index * 4)) & 0b1111;
+    }
+
+    BitField<0, 16, u32> output_mask;
+
+    // 0x28E, CODETRANSFER_END
+    INSERT_PADDING_WORDS(0x2);
+
+    struct {
+        enum Format : u32 {
+            FLOAT24 = 0,
+            FLOAT32 = 1,
+        };
+
+        bool IsFloat32() const {
+            return format == FLOAT32;
+        }
+
+        union {
+            // Index of the next uniform to write to
+            // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid
+            // indices
+            // TODO: Maybe the uppermost index is for the geometry shader? Investigate!
+            BitField<0, 7, u32> index;
+
+            BitField<31, 1, Format> format;
+        };
+
+        // Writing to these registers sets the current uniform.
+        u32 set_value[8];
+
+    } uniform_setup;
+
+    INSERT_PADDING_WORDS(0x2);
+
+    struct {
+        // Offset of the next instruction to write code to.
+        // Incremented with each instruction write.
+        u32 offset;
+
+        // Writing to these registers sets the "current" word in the shader program.
+        u32 set_word[8];
+    } program;
+
+    INSERT_PADDING_WORDS(0x1);
+
+    // This register group is used to load an internal table of swizzling patterns,
+    // which are indexed by each shader instruction to specify vector component swizzling.
+    struct {
+        // Offset of the next swizzle pattern to write code to.
+        // Incremented with each instruction write.
+        u32 offset;
+
+        // Writing to these registers sets the current swizzle pattern in the table.
+        u32 set_word[8];
+    } swizzle_patterns;
+
+    INSERT_PADDING_WORDS(0x2);
+};
+
+static_assert(sizeof(ShaderRegs) == 0x30 * sizeof(u32), "ShaderRegs struct has incorrect size");
+
+} // namespace Pica
diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp
index 916ea8823..840777a66 100644
--- a/src/video_core/shader/shader.cpp
+++ b/src/video_core/shader/shader.cpp
@@ -66,7 +66,7 @@ OutputVertex OutputVertex::FromAttributeBuffer(const RasterizerRegs& regs, Attri
     return ret;
 }
 
-void UnitState::LoadInput(const Regs::ShaderConfig& config, const AttributeBuffer& input) {
+void UnitState::LoadInput(const ShaderRegs& config, const AttributeBuffer& input) {
     const unsigned max_attribute = config.max_input_attribute_index;
 
     for (unsigned attr = 0; attr <= max_attribute; ++attr) {
@@ -75,7 +75,7 @@ void UnitState::LoadInput(const Regs::ShaderConfig& config, const AttributeBuffe
     }
 }
 
-void UnitState::WriteOutput(const Regs::ShaderConfig& config, AttributeBuffer& output) {
+void UnitState::WriteOutput(const ShaderRegs& config, AttributeBuffer& output) {
     unsigned int output_i = 0;
     for (unsigned int reg : Common::BitSet<u32>(config.output_mask)) {
         output.attr[output_i++] = registers.output[reg];
diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h
index e4b68f958..a469e294b 100644
--- a/src/video_core/shader/shader.h
+++ b/src/video_core/shader/shader.h
@@ -116,9 +116,9 @@ struct UnitState {
      * @param config Shader configuration registers corresponding to the unit.
      * @param input Attribute buffer to load into the input registers.
      */
-    void LoadInput(const Regs::ShaderConfig& config, const AttributeBuffer& input);
+    void LoadInput(const ShaderRegs& config, const AttributeBuffer& input);
 
-    void WriteOutput(const Regs::ShaderConfig& config, AttributeBuffer& output);
+    void WriteOutput(const ShaderRegs& config, AttributeBuffer& output);
 };
 
 struct ShaderSetup {
diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp
index 81522b8f5..f4d1c46c5 100644
--- a/src/video_core/shader/shader_interpreter.cpp
+++ b/src/video_core/shader/shader_interpreter.cpp
@@ -669,7 +669,7 @@ void InterpreterEngine::Run(const ShaderSetup& setup, UnitState& state) const {
 
 DebugData<true> InterpreterEngine::ProduceDebugInfo(const ShaderSetup& setup,
                                                     const AttributeBuffer& input,
-                                                    const Regs::ShaderConfig& config) const {
+                                                    const ShaderRegs& config) const {
     UnitState state;
     DebugData<true> debug_data;
 
diff --git a/src/video_core/shader/shader_interpreter.h b/src/video_core/shader/shader_interpreter.h
index d7a61e122..5682b3a39 100644
--- a/src/video_core/shader/shader_interpreter.h
+++ b/src/video_core/shader/shader_interpreter.h
@@ -23,7 +23,7 @@ public:
      * @return Debug information for this shader with regards to the given vertex
      */
     DebugData<true> ProduceDebugInfo(const ShaderSetup& setup, const AttributeBuffer& input,
-                                     const Regs::ShaderConfig& config) const;
+                                     const ShaderRegs& config) const;
 };
 
 } // namespace