summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-01-13 23:55:56 -0200
committerGravatar Yuri Kunde Schlesner2015-01-14 05:20:12 -0200
commit5961a2852dc2b603a896afd9b38b0ded26503849 (patch)
tree124f746b6cb1fefc7ac1a29de7bdb42d92a74b59 /src/core/hle
parentGPU: Fire GPU interrupts at the correct places. (diff)
downloadyuzu-5961a2852dc2b603a896afd9b38b0ded26503849.tar.gz
yuzu-5961a2852dc2b603a896afd9b38b0ded26503849.tar.xz
yuzu-5961a2852dc2b603a896afd9b38b0ded26503849.zip
GSP: Update framebuffer info on all interrupts
Hardware testing determined that the GSP processes shared memory framebuffer update info even when no memory transfer or filling GX commands are used. They are now updated on every interrupt, which isn't confirmed correct but matches hardware behaviour more closely. This also reverts the hack introduced in #404. It made a few games behave better, but I believe it's incorrect and also breaks other games.
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/service/gsp_gpu.cpp25
1 files changed, 13 insertions, 12 deletions
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 9504ab5bb..00a941658 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -218,6 +218,19 @@ void SignalInterrupt(InterruptId interrupt_id) {
218 218
219 interrupt_relay_queue->slot[next] = interrupt_id; 219 interrupt_relay_queue->slot[next] = interrupt_id;
220 interrupt_relay_queue->error_code = 0x0; // No error 220 interrupt_relay_queue->error_code = 0x0; // No error
221
222 // Update framebuffer information if requested
223 // TODO(yuriks): Confirm where this code should be called. It is definitely updated without
224 // executing any GSP commands, only waiting on the event.
225 for (int screen_id = 0; screen_id < 2; ++screen_id) {
226 FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id);
227
228 if (info->is_dirty) {
229 SetBufferSwap(screen_id, info->framebuffer_info[info->index]);
230 }
231
232 info->is_dirty = false;
233 }
221 } 234 }
222 Kernel::SignalEvent(g_interrupt_event); 235 Kernel::SignalEvent(g_interrupt_event);
223} 236}
@@ -281,18 +294,6 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
281 WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_size), params.out_buffer_size); 294 WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_size), params.out_buffer_size);
282 WriteGPURegister(GPU_REG_INDEX(display_transfer_config.flags), params.flags); 295 WriteGPURegister(GPU_REG_INDEX(display_transfer_config.flags), params.flags);
283 WriteGPURegister(GPU_REG_INDEX(display_transfer_config.trigger), 1); 296 WriteGPURegister(GPU_REG_INDEX(display_transfer_config.trigger), 1);
284
285 // Update framebuffer information if requested
286 for (int screen_id = 0; screen_id < 2; ++screen_id) {
287 FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id);
288
289 if (info->is_dirty) {
290 SetBufferSwap(screen_id, info->framebuffer_info[info->index]);
291 info->framebuffer_info->active_fb = info->framebuffer_info->active_fb ^ 1;
292 }
293
294 info->is_dirty = false;
295 }
296 break; 297 break;
297 } 298 }
298 299