From ebe44ccc0b368acace3865a2b71976280fb365b0 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 5 Oct 2019 15:15:00 +1000 Subject: [PATCH] GPU: Fix broken VRAM->CPU transfers at >1x resolution scale --- src/core/gpu_hw_opengl.cpp | 37 ++++++++++++++++++++----------- src/duckstation/main.cpp | 16 +++++++------ src/duckstation/sdl_interface.cpp | 2 +- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 8b9ecd09a..57cdb4919 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -237,23 +237,32 @@ void GPU_HW_OpenGL::ClearFramebuffer() void GPU_HW_OpenGL::DestroyFramebuffer() { - glDeleteFramebuffers(1, &m_vram_read_fbo); - m_vram_read_fbo = 0; + if (m_vram_read_fbo != 0) + { + glDeleteFramebuffers(1, &m_vram_read_fbo); + m_vram_read_fbo = 0; + } m_vram_read_texture.reset(); - glDeleteFramebuffers(1, &m_vram_fbo); - m_vram_fbo = 0; + if (m_vram_fbo != 0) + { + glDeleteFramebuffers(1, &m_vram_fbo); + m_vram_fbo = 0; + } m_vram_texture.reset(); - if (m_vram_downsample_texture) + if (m_vram_downsample_fbo != 0) { glDeleteFramebuffers(1, &m_vram_downsample_fbo); m_vram_downsample_fbo = 0; - m_vram_downsample_texture.reset(); } + m_vram_downsample_texture.reset(); - glDeleteFramebuffers(1, &m_display_fbo); - m_display_fbo = 0; + if (m_display_fbo != 0) + { + glDeleteFramebuffers(1, &m_display_fbo); + m_display_fbo = 0; + } m_display_texture.reset(); } @@ -477,6 +486,7 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) { // we need to convert RGBA8 -> RGBA5551 std::vector temp_buffer(width * height); + const u32 flipped_y = VRAM_HEIGHT - y - height; // downscaling to 1xIR. if (m_resolution_scale > 1) @@ -487,21 +497,22 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) const u32 scaled_y = y * m_resolution_scale; const u32 scaled_width = width * m_resolution_scale; const u32 scaled_height = height * m_resolution_scale; + const u32 scaled_flipped_y = texture_height - scaled_y - scaled_height; - glDisable(GL_SCISSOR_TEST); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_vram_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_vram_downsample_fbo); - glBlitFramebuffer(scaled_x, texture_height - scaled_y - height, scaled_x + scaled_width, scaled_y + scaled_height, - 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glDisable(GL_SCISSOR_TEST); + glBlitFramebuffer(scaled_x, scaled_flipped_y, scaled_x + scaled_width, scaled_flipped_y + scaled_height, 0, 0, + width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glEnable(GL_SCISSOR_TEST); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_vram_downsample_fbo); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_vram_fbo); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_buffer.data()); - glEnable(GL_SCISSOR_TEST); } else { + glReadPixels(x, flipped_y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_buffer.data()); glBindFramebuffer(GL_READ_FRAMEBUFFER, m_vram_fbo); - glReadPixels(x, VRAM_HEIGHT - y - height, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_buffer.data()); } // reverse copy because of lower-left origin diff --git a/src/duckstation/main.cpp b/src/duckstation/main.cpp index ed8abc837..b78f8c32c 100644 --- a/src/duckstation/main.cpp +++ b/src/duckstation/main.cpp @@ -86,15 +86,17 @@ static int Run(int argc, char* argv[]) int main(int argc, char* argv[]) { // set log flags - g_pLog->SetConsoleOutputParams(true, nullptr, LOGLEVEL_DEBUG); - // g_pLog->SetConsoleOutputParams(true, "GPU GPU_HW_OpenGL SPU Pad DigitalController", LOGLEVEL_DEBUG); - // g_pLog->SetConsoleOutputParams(true, "GPU GPU_HW_OpenGL SPU Pad DigitalController InterruptController", LOGLEVEL_DEBUG); - #ifdef Y_BUILD_CONFIG_RELEASE - g_pLog->SetFilterLevel(LOGLEVEL_INFO); - // g_pLog->SetFilterLevel(LOGLEVEL_DEV); - // g_pLog->SetFilterLevel(LOGLEVEL_PROFILE); + const LOGLEVEL level = LOGLEVEL_INFO; + // const LOGLEVEL level = LOGLEVEL_DEV; + // const LOGLEVEL level = LOGLEVEL_PROFILE; + // g_pLog->SetConsoleOutputParams(true, nullptr, level); + g_pLog->SetConsoleOutputParams(true, "Pad SPU", level); + g_pLog->SetFilterLevel(level); #else + // g_pLog->SetConsoleOutputParams(true, nullptr, LOGLEVEL_DEBUG); + // g_pLog->SetConsoleOutputParams(true, "GPU GPU_HW_OpenGL SPU Pad DigitalController", LOGLEVEL_DEBUG); + g_pLog->SetConsoleOutputParams(true, "GPU GPU_HW_OpenGL SPU Pad DigitalController InterruptController", LOGLEVEL_DEBUG); // g_pLog->SetFilterLevel(LOGLEVEL_TRACE); g_pLog->SetFilterLevel(LOGLEVEL_DEBUG); // g_pLog->SetFilterLevel(LOGLEVEL_DEV); diff --git a/src/duckstation/sdl_interface.cpp b/src/duckstation/sdl_interface.cpp index 50efd0014..f8f2868f9 100644 --- a/src/duckstation/sdl_interface.cpp +++ b/src/duckstation/sdl_interface.cpp @@ -108,7 +108,7 @@ bool SDLInterface::CreateGLContext() } #endif - // SDL_GL_SetSwapInterval(0); + SDL_GL_SetSwapInterval(0); return true; }