citra-emu
/
citra-canary
Archived
1
0
Fork 0

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.
This commit is contained in:
Yuri Kunde Schlesner 2015-01-13 23:55:56 -02:00
parent 98e3274935
commit 5961a2852d
2 changed files with 14 additions and 15 deletions

View File

@ -218,6 +218,19 @@ void SignalInterrupt(InterruptId interrupt_id) {
interrupt_relay_queue->slot[next] = interrupt_id; interrupt_relay_queue->slot[next] = interrupt_id;
interrupt_relay_queue->error_code = 0x0; // No error interrupt_relay_queue->error_code = 0x0; // No error
// Update framebuffer information if requested
// TODO(yuriks): Confirm where this code should be called. It is definitely updated without
// executing any GSP commands, only waiting on the event.
for (int screen_id = 0; screen_id < 2; ++screen_id) {
FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id);
if (info->is_dirty) {
SetBufferSwap(screen_id, info->framebuffer_info[info->index]);
}
info->is_dirty = false;
}
} }
Kernel::SignalEvent(g_interrupt_event); Kernel::SignalEvent(g_interrupt_event);
} }
@ -281,18 +294,6 @@ static void ExecuteCommand(const Command& command, u32 thread_id) {
WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_size), params.out_buffer_size); WriteGPURegister(GPU_REG_INDEX(display_transfer_config.output_size), params.out_buffer_size);
WriteGPURegister(GPU_REG_INDEX(display_transfer_config.flags), params.flags); WriteGPURegister(GPU_REG_INDEX(display_transfer_config.flags), params.flags);
WriteGPURegister(GPU_REG_INDEX(display_transfer_config.trigger), 1); WriteGPURegister(GPU_REG_INDEX(display_transfer_config.trigger), 1);
// Update framebuffer information if requested
for (int screen_id = 0; screen_id < 2; ++screen_id) {
FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id);
if (info->is_dirty) {
SetBufferSwap(screen_id, info->framebuffer_info[info->index]);
info->framebuffer_info->active_fb = info->framebuffer_info->active_fb ^ 1;
}
info->is_dirty = false;
}
break; break;
} }

View File

@ -88,10 +88,8 @@ void RendererOpenGL::SwapBuffers() {
void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer, void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig& framebuffer,
const TextureInfo& texture) { const TextureInfo& texture) {
// TODO: Why are active_fb and the valid framebuffer flipped compared to 3dbrew documentation
// and GSP definitions?
const VAddr framebuffer_vaddr = Memory::PhysicalToVirtualAddress( const VAddr framebuffer_vaddr = Memory::PhysicalToVirtualAddress(
framebuffer.active_fb == 0 ? framebuffer.address_left2 : framebuffer.address_left1); framebuffer.active_fb == 0 ? framebuffer.address_left1 : framebuffer.address_left2);
LOG_TRACE(Render_OpenGL, "0x%08x bytes from 0x%08x(%dx%d), fmt %x", LOG_TRACE(Render_OpenGL, "0x%08x bytes from 0x%08x(%dx%d), fmt %x",
framebuffer.stride * framebuffer.height, framebuffer.stride * framebuffer.height,