summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2017-01-28 13:58:51 -0800
committerGravatar Yuri Kunde Schlesner2017-02-08 22:13:25 -0800
commit602f57da387da2bf702aa149124c14861b5d27d8 (patch)
tree67efd173c6f50d09887acada1031f576c25ed1a0 /src
parentMerge pull request #2482 from yuriks/pica-refactor (diff)
downloadyuzu-602f57da387da2bf702aa149124c14861b5d27d8.tar.gz
yuzu-602f57da387da2bf702aa149124c14861b5d27d8.tar.xz
yuzu-602f57da387da2bf702aa149124c14861b5d27d8.zip
VideoCore: Use union to index into Regs struct
Also remove some unused members.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/command_processor.cpp12
-rw-r--r--src/video_core/regs.h62
2 files changed, 28 insertions, 46 deletions
diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp
index 91c0ca4e6..ea541200b 100644
--- a/src/video_core/command_processor.cpp
+++ b/src/video_core/command_processor.cpp
@@ -49,19 +49,23 @@ MICROPROFILE_DEFINE(GPU_Drawing, "GPU", "Drawing", MP_RGB(50, 50, 240));
49static void WritePicaReg(u32 id, u32 value, u32 mask) { 49static void WritePicaReg(u32 id, u32 value, u32 mask) {
50 auto& regs = g_state.regs; 50 auto& regs = g_state.regs;
51 51
52 if (id >= regs.NumIds()) 52 if (id >= Regs::NUM_REGS) {
53 LOG_ERROR(HW_GPU,
54 "Commandlist tried to write to invalid register 0x%03X (value: %08X, mask: %X)",
55 id, value, mask);
53 return; 56 return;
57 }
54 58
55 // TODO: Figure out how register masking acts on e.g. vs.uniform_setup.set_value 59 // TODO: Figure out how register masking acts on e.g. vs.uniform_setup.set_value
56 u32 old_value = regs[id]; 60 u32 old_value = regs.reg_array[id];
57 61
58 const u32 write_mask = expand_bits_to_bytes[mask]; 62 const u32 write_mask = expand_bits_to_bytes[mask];
59 63
60 regs[id] = (old_value & ~write_mask) | (value & write_mask); 64 regs.reg_array[id] = (old_value & ~write_mask) | (value & write_mask);
61 65
62 // Double check for is_pica_tracing to avoid call overhead 66 // Double check for is_pica_tracing to avoid call overhead
63 if (DebugUtils::IsPicaTracing()) { 67 if (DebugUtils::IsPicaTracing()) {
64 DebugUtils::OnPicaRegWrite({(u16)id, (u16)mask, regs[id]}); 68 DebugUtils::OnPicaRegWrite({(u16)id, (u16)mask, regs.reg_array[id]});
65 } 69 }
66 70
67 if (g_debug_context) 71 if (g_debug_context)
diff --git a/src/video_core/regs.h b/src/video_core/regs.h
index f25edde27..e38ab4333 100644
--- a/src/video_core/regs.h
+++ b/src/video_core/regs.h
@@ -45,46 +45,31 @@ namespace Pica {
45#endif // _MSC_VER 45#endif // _MSC_VER
46 46
47struct Regs { 47struct Regs {
48 INSERT_PADDING_WORDS(0x10); 48 static constexpr size_t NUM_REGS = 0x300;
49 u32 trigger_irq; 49
50 INSERT_PADDING_WORDS(0x2f); 50 union {
51 RasterizerRegs rasterizer; 51 struct {
52 TexturingRegs texturing; 52 INSERT_PADDING_WORDS(0x10);
53 FramebufferRegs framebuffer; 53 u32 trigger_irq;
54 LightingRegs lighting; 54 INSERT_PADDING_WORDS(0x2f);
55 PipelineRegs pipeline; 55 RasterizerRegs rasterizer;
56 ShaderRegs gs; 56 TexturingRegs texturing;
57 ShaderRegs vs; 57 FramebufferRegs framebuffer;
58 INSERT_PADDING_WORDS(0x20); 58 LightingRegs lighting;
59 PipelineRegs pipeline;
60 ShaderRegs gs;
61 ShaderRegs vs;
62 INSERT_PADDING_WORDS(0x20);
63 };
64 std::array<u32, NUM_REGS> reg_array;
65 };
59 66
60 // Map register indices to names readable by humans 67 // Map register indices to names readable by humans
61 // Used for debugging purposes, so performance is not an issue here
62 static std::string GetCommandName(int index); 68 static std::string GetCommandName(int index);
63
64 static constexpr size_t NumIds() {
65 return sizeof(Regs) / sizeof(u32);
66 }
67
68 const u32& operator[](int index) const {
69 const u32* content = reinterpret_cast<const u32*>(this);
70 return content[index];
71 }
72
73 u32& operator[](int index) {
74 u32* content = reinterpret_cast<u32*>(this);
75 return content[index];
76 }
77
78private:
79 /*
80 * Most physical addresses which Pica registers refer to are 8-byte aligned.
81 * This function should be used to get the address from a raw register value.
82 */
83 static inline u32 DecodeAddressRegister(u32 register_value) {
84 return register_value * 8;
85 }
86}; 69};
87 70
71static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Regs struct has wrong size");
72
88// TODO: MSVC does not support using offsetof() on non-static data members even though this 73// TODO: MSVC does not support using offsetof() on non-static data members even though this
89// is technically allowed since C++11. This macro should be enabled once MSVC adds 74// is technically allowed since C++11. This macro should be enabled once MSVC adds
90// support for that. 75// support for that.
@@ -154,11 +139,4 @@ ASSERT_REG_POSITION(vs, 0x2b0);
154#undef ASSERT_REG_POSITION 139#undef ASSERT_REG_POSITION
155#endif // !defined(_MSC_VER) 140#endif // !defined(_MSC_VER)
156 141
157// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value
158// anyway.
159static_assert(sizeof(Regs) <= 0x300 * sizeof(u32),
160 "Register set structure larger than it should be");
161static_assert(sizeof(Regs) >= 0x300 * sizeof(u32),
162 "Register set structure smaller than it should be");
163
164} // namespace Pica 142} // namespace Pica