Ver código fonte

VideoCore: Use union to index into Regs struct

Also remove some unused members.
Yuri Kunde Schlesner 9 anos atrás
pai
commit
602f57da38
2 arquivos alterados com 28 adições e 46 exclusões
  1. 8 4
      src/video_core/command_processor.cpp
  2. 20 42
      src/video_core/regs.h

+ 8 - 4
src/video_core/command_processor.cpp

@@ -49,19 +49,23 @@ MICROPROFILE_DEFINE(GPU_Drawing, "GPU", "Drawing", MP_RGB(50, 50, 240));
 static void WritePicaReg(u32 id, u32 value, u32 mask) {
     auto& regs = g_state.regs;
 
-    if (id >= regs.NumIds())
+    if (id >= Regs::NUM_REGS) {
+        LOG_ERROR(HW_GPU,
+                  "Commandlist tried to write to invalid register 0x%03X (value: %08X, mask: %X)",
+                  id, value, mask);
         return;
+    }
 
     // TODO: Figure out how register masking acts on e.g. vs.uniform_setup.set_value
-    u32 old_value = regs[id];
+    u32 old_value = regs.reg_array[id];
 
     const u32 write_mask = expand_bits_to_bytes[mask];
 
-    regs[id] = (old_value & ~write_mask) | (value & write_mask);
+    regs.reg_array[id] = (old_value & ~write_mask) | (value & write_mask);
 
     // Double check for is_pica_tracing to avoid call overhead
     if (DebugUtils::IsPicaTracing()) {
-        DebugUtils::OnPicaRegWrite({(u16)id, (u16)mask, regs[id]});
+        DebugUtils::OnPicaRegWrite({(u16)id, (u16)mask, regs.reg_array[id]});
     }
 
     if (g_debug_context)

+ 20 - 42
src/video_core/regs.h

@@ -45,46 +45,31 @@ namespace Pica {
 #endif // _MSC_VER
 
 struct Regs {
-    INSERT_PADDING_WORDS(0x10);
-    u32 trigger_irq;
-    INSERT_PADDING_WORDS(0x2f);
-    RasterizerRegs rasterizer;
-    TexturingRegs texturing;
-    FramebufferRegs framebuffer;
-    LightingRegs lighting;
-    PipelineRegs pipeline;
-    ShaderRegs gs;
-    ShaderRegs vs;
-    INSERT_PADDING_WORDS(0x20);
+    static constexpr size_t NUM_REGS = 0x300;
+
+    union {
+        struct {
+            INSERT_PADDING_WORDS(0x10);
+            u32 trigger_irq;
+            INSERT_PADDING_WORDS(0x2f);
+            RasterizerRegs rasterizer;
+            TexturingRegs texturing;
+            FramebufferRegs framebuffer;
+            LightingRegs lighting;
+            PipelineRegs pipeline;
+            ShaderRegs gs;
+            ShaderRegs vs;
+            INSERT_PADDING_WORDS(0x20);
+        };
+        std::array<u32, NUM_REGS> reg_array;
+    };
 
     // Map register indices to names readable by humans
-    // Used for debugging purposes, so performance is not an issue here
     static std::string GetCommandName(int index);
-
-    static constexpr size_t NumIds() {
-        return sizeof(Regs) / sizeof(u32);
-    }
-
-    const u32& operator[](int index) const {
-        const u32* content = reinterpret_cast<const u32*>(this);
-        return content[index];
-    }
-
-    u32& operator[](int index) {
-        u32* content = reinterpret_cast<u32*>(this);
-        return content[index];
-    }
-
-private:
-    /*
-    * Most physical addresses which Pica registers refer to are 8-byte aligned.
-    * This function should be used to get the address from a raw register value.
-    */
-    static inline u32 DecodeAddressRegister(u32 register_value) {
-        return register_value * 8;
-    }
 };
 
+static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Regs struct has wrong size");
+
 // TODO: MSVC does not support using offsetof() on non-static data members even though this
 //       is technically allowed since C++11. This macro should be enabled once MSVC adds
 //       support for that.
@@ -154,11 +139,4 @@ ASSERT_REG_POSITION(vs, 0x2b0);
 #undef ASSERT_REG_POSITION
 #endif // !defined(_MSC_VER)
 
-// 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),
-              "Register set structure larger than it should be");
-static_assert(sizeof(Regs) >= 0x300 * sizeof(u32),
-              "Register set structure smaller than it should be");
-
 } // namespace Pica