diff --git a/src/pse-sdl/sdl_interface.cpp b/src/pse-sdl/sdl_interface.cpp index 78112595c..10e5caa5f 100644 --- a/src/pse-sdl/sdl_interface.cpp +++ b/src/pse-sdl/sdl_interface.cpp @@ -129,13 +129,15 @@ void main() #version 330 core uniform sampler2D samp0; +uniform vec4 u_src_rect; in vec2 v_tex0; out vec4 o_col0; void main() { - o_col0 = texture(samp0, v_tex0); + vec2 coords = u_src_rect.xy + v_tex0 * u_src_rect.zw; + o_col0 = texture(samp0, coords); } )"; @@ -146,9 +148,10 @@ void main() if (!m_display_program.Link()) return false; - m_display_program.RegisterUniform("samp0"); m_display_program.Bind(); - m_display_program.Uniform1i(0, 0); + m_display_program.RegisterUniform("u_src_rect"); + m_display_program.RegisterUniform("samp0"); + m_display_program.Uniform1i(1, 0); glGenVertexArrays(1, &m_display_vao); return true; @@ -380,6 +383,11 @@ void SDLInterface::RenderDisplay() glDisable(GL_SCISSOR_TEST); glDepthMask(GL_FALSE); m_display_program.Bind(); + m_display_program.Uniform4f( + 0, static_cast(m_display_texture_offset_x) / static_cast(m_display_texture->GetWidth()), + static_cast(m_display_texture_offset_y) / static_cast(m_display_texture->GetHeight()), + static_cast(m_display_texture_width) / static_cast(m_display_texture->GetWidth()), + static_cast(m_display_texture_height) / static_cast(m_display_texture->GetHeight())); m_display_texture->Bind(); glBindVertexArray(m_display_vao); glDrawArrays(GL_TRIANGLES, 0, 3); @@ -449,7 +457,6 @@ void SDLInterface::RenderMainMenuBar() ImGui::EndMenu(); } - ImGui::SetCursorPosX(ImGui::GetIO().DisplaySize.x - 80.0f); ImGui::Text("FPS: %.2f", m_fps); diff --git a/src/pse/gpu_hw_opengl.cpp b/src/pse/gpu_hw_opengl.cpp index 12efa73bd..3454ba998 100644 --- a/src/pse/gpu_hw_opengl.cpp +++ b/src/pse/gpu_hw_opengl.cpp @@ -37,7 +37,7 @@ void GPU_HW_OpenGL::RenderUI() { GPU_HW::RenderUI(); - ImGui::SetNextWindowSize(ImVec2(300.0f, 100.0f), ImGuiCond_Once); + ImGui::SetNextWindowSize(ImVec2(300.0f, 130.0f), ImGuiCond_Once); const bool is_null_frame = m_stats.num_batches == 0; if (!is_null_frame) @@ -72,6 +72,8 @@ void GPU_HW_OpenGL::RenderUI() ImGui::NextColumn(); ImGui::Columns(1); + + ImGui::Checkbox("Show VRAM##gpu_gl_show_vram", &m_show_vram); } ImGui::End(); @@ -103,6 +105,15 @@ void GPU_HW_OpenGL::CreateFramebuffer() glBindFramebuffer(GL_FRAMEBUFFER, m_vram_read_fbo_id); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_vram_read_texture->GetGLId(), 0); Assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + + m_display_texture = std::make_unique(VRAM_WIDTH, VRAM_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false); + m_display_texture->Bind(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glGenFramebuffers(1, &m_display_fbo_id); + glBindFramebuffer(GL_FRAMEBUFFER, m_display_fbo_id); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_display_texture->GetGLId(), 0); + Assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); } void GPU_HW_OpenGL::ClearFramebuffer() @@ -272,7 +283,28 @@ void GPU_HW_OpenGL::SetBlendState() void GPU_HW_OpenGL::UpdateDisplay() { GPU_HW::UpdateDisplay(); - m_system->GetHostInterface()->SetDisplayTexture(m_framebuffer_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT); + + // TODO: 24-bit support. + if (m_show_vram) + { + m_system->GetHostInterface()->SetDisplayTexture(m_framebuffer_texture.get(), 0, 0, VRAM_WIDTH, VRAM_HEIGHT); + } + else + { + const u32 display_width = m_crtc_state.horizontal_resolution; + const u32 display_height = m_crtc_state.vertical_resolution; + const u32 vram_offset_x = m_crtc_state.regs.X; + const u32 vram_offset_y = m_crtc_state.regs.Y; + const u32 copy_width = + ((vram_offset_x + display_width) > VRAM_WIDTH) ? (VRAM_WIDTH - vram_offset_x) : display_width; + const u32 copy_height = + ((vram_offset_y + display_height) > VRAM_HEIGHT) ? (VRAM_HEIGHT - vram_offset_y) : display_height; + glCopyImageSubData(m_framebuffer_texture->GetGLId(), GL_TEXTURE_2D, 0, vram_offset_x, + VRAM_HEIGHT - vram_offset_y - copy_height, 0, m_display_texture->GetGLId(), GL_TEXTURE_2D, 0, 0, + 0, 0, copy_width, copy_height, 1); + + m_system->GetHostInterface()->SetDisplayTexture(m_display_texture.get(), 0, 0, copy_width, copy_height); + } } void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) diff --git a/src/pse/gpu_hw_opengl.h b/src/pse/gpu_hw_opengl.h index 114c1010f..7be5bfa7d 100644 --- a/src/pse/gpu_hw_opengl.h +++ b/src/pse/gpu_hw_opengl.h @@ -58,6 +58,9 @@ private: GLuint m_vram_read_fbo_id = 0; bool m_vram_read_texture_dirty = true; + std::unique_ptr m_display_texture; + GLuint m_display_fbo_id = 0; + GLuint m_vertex_buffer = 0; GLuint m_vao_id = 0; GLuint m_attributeless_vao_id = 0; @@ -67,4 +70,5 @@ private: GLStats m_stats = {}; GLStats m_last_stats = {}; + bool m_show_vram = false; };