summaryrefslogtreecommitdiff
path: root/src/core/hw/gpu.cpp
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2014-08-03 16:00:52 +0200
committerGravatar Tony Wasserka2014-08-12 02:17:21 +0200
commit9c781a6c7646a3f30c23adae75e1879b7fc47d0f (patch)
tree76f32e7dc447e661f9f34303609cf4aed23d7a5b /src/core/hw/gpu.cpp
parentMerge pull request #40 from bentley/master (diff)
downloadyuzu-9c781a6c7646a3f30c23adae75e1879b7fc47d0f.tar.gz
yuzu-9c781a6c7646a3f30c23adae75e1879b7fc47d0f.tar.xz
yuzu-9c781a6c7646a3f30c23adae75e1879b7fc47d0f.zip
Remove the fancy RegisterSet class introduced in 4c2bff61e.
While it was some nice and fancy template usage, it ultimately had many practical issues regarding length of involved expressions under regular usage as well as common code completion tools not being able to handle the structures. Instead, we now use a more conventional approach which is a lot more clean to use.
Diffstat (limited to 'src/core/hw/gpu.cpp')
-rw-r--r--src/core/hw/gpu.cpp47
1 files changed, 23 insertions, 24 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index d94c2329b..fd40f8ac0 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -19,7 +19,7 @@
19 19
20namespace GPU { 20namespace GPU {
21 21
22RegisterSet<u32, Regs> g_regs; 22Regs g_regs;
23 23
24u32 g_cur_line = 0; ///< Current vertical screen line 24u32 g_cur_line = 0; ///< Current vertical screen line
25u64 g_last_line_ticks = 0; ///< CPU tick count from last vertical screen line 25u64 g_last_line_ticks = 0; ///< CPU tick count from last vertical screen line
@@ -32,8 +32,8 @@ void SetFramebufferLocation(const FramebufferLocation mode) {
32 switch (mode) { 32 switch (mode) {
33 case FRAMEBUFFER_LOCATION_FCRAM: 33 case FRAMEBUFFER_LOCATION_FCRAM:
34 { 34 {
35 auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); 35 auto& framebuffer_top = g_regs.framebuffer_config[0];
36 auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); 36 auto& framebuffer_sub = g_regs.framebuffer_config[1];
37 37
38 framebuffer_top.address_left1 = PADDR_TOP_LEFT_FRAME1; 38 framebuffer_top.address_left1 = PADDR_TOP_LEFT_FRAME1;
39 framebuffer_top.address_left2 = PADDR_TOP_LEFT_FRAME2; 39 framebuffer_top.address_left2 = PADDR_TOP_LEFT_FRAME2;
@@ -48,8 +48,8 @@ void SetFramebufferLocation(const FramebufferLocation mode) {
48 48
49 case FRAMEBUFFER_LOCATION_VRAM: 49 case FRAMEBUFFER_LOCATION_VRAM:
50 { 50 {
51 auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); 51 auto& framebuffer_top = g_regs.framebuffer_config[0];
52 auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); 52 auto& framebuffer_sub = g_regs.framebuffer_config[1];
53 53
54 framebuffer_top.address_left1 = PADDR_VRAM_TOP_LEFT_FRAME1; 54 framebuffer_top.address_left1 = PADDR_VRAM_TOP_LEFT_FRAME1;
55 framebuffer_top.address_left2 = PADDR_VRAM_TOP_LEFT_FRAME2; 55 framebuffer_top.address_left2 = PADDR_VRAM_TOP_LEFT_FRAME2;
@@ -107,13 +107,12 @@ inline void Read(T &var, const u32 raw_addr) {
107 int index = addr / 4; 107 int index = addr / 4;
108 108
109 // Reads other than u32 are untested, so I'd rather have them abort than silently fail 109 // Reads other than u32 are untested, so I'd rather have them abort than silently fail
110 if (index >= Regs::NumIds || !std::is_same<T,u32>::value) 110 if (index >= Regs::NumIds() || !std::is_same<T,u32>::value) {
111 {
112 ERROR_LOG(GPU, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr); 111 ERROR_LOG(GPU, "unknown Read%d @ 0x%08X", sizeof(var) * 8, addr);
113 return; 112 return;
114 } 113 }
115 114
116 var = g_regs[static_cast<Regs::Id>(addr / 4)]; 115 var = g_regs[addr / 4];
117} 116}
118 117
119template <typename T> 118template <typename T>
@@ -122,22 +121,22 @@ inline void Write(u32 addr, const T data) {
122 int index = addr / 4; 121 int index = addr / 4;
123 122
124 // Writes other than u32 are untested, so I'd rather have them abort than silently fail 123 // Writes other than u32 are untested, so I'd rather have them abort than silently fail
125 if (index >= Regs::NumIds || !std::is_same<T,u32>::value) 124 if (index >= Regs::NumIds() || !std::is_same<T,u32>::value) {
126 {
127 ERROR_LOG(GPU, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr); 125 ERROR_LOG(GPU, "unknown Write%d 0x%08X @ 0x%08X", sizeof(data) * 8, data, addr);
128 return; 126 return;
129 } 127 }
130 128
131 g_regs[static_cast<Regs::Id>(index)] = data; 129 g_regs[index] = data;
132 130
133 switch (static_cast<Regs::Id>(index)) { 131 switch (index) {
134 132
135 // Memory fills are triggered once the fill value is written. 133 // Memory fills are triggered once the fill value is written.
136 // NOTE: This is not verified. 134 // NOTE: This is not verified.
137 case Regs::MemoryFill + 3: 135 case GPU_REG_INDEX_WORKAROUND(memory_fill_config[0].value, 0x00004 + 0x3):
138 case Regs::MemoryFill + 7: 136 case GPU_REG_INDEX_WORKAROUND(memory_fill_config[1].value, 0x00008 + 0x3):
139 { 137 {
140 const auto& config = g_regs.Get<Regs::MemoryFill>(static_cast<Regs::Id>(index - 3)); 138 const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].value));
139 const auto& config = g_regs.memory_fill_config[is_second_filler];
141 140
142 // TODO: Not sure if this check should be done at GSP level instead 141 // TODO: Not sure if this check should be done at GSP level instead
143 if (config.address_start) { 142 if (config.address_start) {
@@ -152,9 +151,9 @@ inline void Write(u32 addr, const T data) {
152 break; 151 break;
153 } 152 }
154 153
155 case Regs::DisplayTransfer + 6: 154 case GPU_REG_INDEX(display_transfer_config.trigger):
156 { 155 {
157 const auto& config = g_regs.Get<Regs::DisplayTransfer>(); 156 const auto& config = g_regs.display_transfer_config;
158 if (config.trigger & 1) { 157 if (config.trigger & 1) {
159 u8* source_pointer = Memory::GetPointer(config.GetPhysicalInputAddress()); 158 u8* source_pointer = Memory::GetPointer(config.GetPhysicalInputAddress());
160 u8* dest_pointer = Memory::GetPointer(config.GetPhysicalOutputAddress()); 159 u8* dest_pointer = Memory::GetPointer(config.GetPhysicalOutputAddress());
@@ -221,13 +220,13 @@ inline void Write(u32 addr, const T data) {
221 break; 220 break;
222 } 221 }
223 222
224 case Regs::CommandProcessor + 4: 223 case GPU_REG_INDEX(command_processor_config.trigger):
225 { 224 {
226 const auto& config = g_regs.Get<Regs::CommandProcessor>(); 225 const auto& config = g_regs.command_processor_config;
227 if (config.trigger & 1) 226 if (config.trigger & 1)
228 { 227 {
229 // u32* buffer = (u32*)Memory::GetPointer(config.address << 3); 228 // u32* buffer = (u32*)Memory::GetPointer(config.GetPhysicalAddress());
230 ERROR_LOG(GPU, "Beginning 0x%08x bytes of commands from address 0x%08x", config.size, config.address << 3); 229 ERROR_LOG(GPU, "Beginning 0x%08x bytes of commands from address 0x%08x", config.size, config.GetPhysicalAddress());
231 // TODO: Process command list! 230 // TODO: Process command list!
232 } 231 }
233 break; 232 break;
@@ -252,7 +251,7 @@ template void Write<u8>(u32 addr, const u8 data);
252 251
253/// Update hardware 252/// Update hardware
254void Update() { 253void Update() {
255 auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); 254 auto& framebuffer_top = g_regs.framebuffer_config[0];
256 u64 current_ticks = Core::g_app_core->GetTicks(); 255 u64 current_ticks = Core::g_app_core->GetTicks();
257 256
258 // Synchronize line... 257 // Synchronize line...
@@ -280,8 +279,8 @@ void Init() {
280// SetFramebufferLocation(FRAMEBUFFER_LOCATION_FCRAM); 279// SetFramebufferLocation(FRAMEBUFFER_LOCATION_FCRAM);
281 SetFramebufferLocation(FRAMEBUFFER_LOCATION_VRAM); 280 SetFramebufferLocation(FRAMEBUFFER_LOCATION_VRAM);
282 281
283 auto& framebuffer_top = g_regs.Get<Regs::FramebufferTop>(); 282 auto& framebuffer_top = g_regs.framebuffer_config[0];
284 auto& framebuffer_sub = g_regs.Get<Regs::FramebufferBottom>(); 283 auto& framebuffer_sub = g_regs.framebuffer_config[1];
285 // TODO: Width should be 240 instead? 284 // TODO: Width should be 240 instead?
286 framebuffer_top.width = 480; 285 framebuffer_top.width = 480;
287 framebuffer_top.height = 400; 286 framebuffer_top.height = 400;