diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 6382468b20..59ee60b945 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -359,6 +359,8 @@ void GLGSRender::on_exit() gl::g_typeless_transfer_buffer.remove(); } + gl::debug::g_vis_texture.reset(); // TODO + gl::destroy_pipe_compiler(); m_prog_buffer.clear(); diff --git a/rpcs3/Emu/RSX/GL/GLPresent.cpp b/rpcs3/Emu/RSX/GL/GLPresent.cpp index 469b8d2d39..e33e1481f2 100644 --- a/rpcs3/Emu/RSX/GL/GLPresent.cpp +++ b/rpcs3/Emu/RSX/GL/GLPresent.cpp @@ -4,6 +4,22 @@ LOG_CHANNEL(screenshot_log, "SCREENSHOT"); +namespace gl +{ + namespace debug + { + std::unique_ptr g_vis_texture; + + void set_vis_texture(texture* visual) + { + const auto target = static_cast(visual->get_target()); + const auto ifmt = static_cast(visual->get_internal_format()); + g_vis_texture.reset(new texture(target, visual->width(), visual->height(), 1, 1, ifmt, visual->format_class())); + glCopyImageSubData(visual->id(), target, 0, 0, 0, 0, g_vis_texture->id(), target, 0, 0, 0, 0, visual->width(), visual->height(), 1); + } + } +} + gl::texture* GLGSRender::get_present_source(gl::present_surface_info* info, const rsx::avconf& avconfig) { gl::texture* image = nullptr; @@ -334,6 +350,30 @@ void GLGSRender::flip(const rsx::display_flip_info_t& info) m_text_printer.print_text(4, 180, width, height, fmt::format("Texture uploads: %15u (%u from CPU - %02u%%)", num_texture_upload, num_texture_upload_miss, texture_upload_miss_ratio)); } + if (gl::debug::g_vis_texture) + { + // Optionally renders a single debug texture to framebuffer. + // Only programmatic access provided at the moment. + // TODO: Migrate to use overlay system. (kd-11) + gl::fbo m_vis_buffer; + m_vis_buffer.create(); + m_vis_buffer.bind(); + m_vis_buffer.color = gl::debug::g_vis_texture->id(); + m_vis_buffer.read_buffer(m_vis_buffer.color); + m_vis_buffer.draw_buffer(m_vis_buffer.color); + + const u32 vis_width = 320; + const u32 vis_height = 240; + areai display_view = areai(aspect_ratio).flipped_vertical(); + display_view.x1 = display_view.x2 - vis_width; + display_view.y1 = vis_height; + + // Blit + const auto src_region = areau{ 0u, 0u, gl::debug::g_vis_texture->width(), gl::debug::g_vis_texture->height() }; + m_vis_buffer.blit(gl::screen, static_cast(src_region), display_view, gl::buffers::color, gl::filter::linear); + m_vis_buffer.remove(); + } + m_frame->flip(m_context); rsx::thread::flip(info); diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 25211e7426..49eacb3145 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -10,6 +10,11 @@ namespace gl { + namespace debug + { + extern void set_vis_texture(texture*); + } + buffer g_typeless_transfer_buffer; GLenum get_target(rsx::texture_dimension_extended type) diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index cecc13b90a..2e360683a1 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -119,5 +119,10 @@ namespace gl void apply_defaults(GLenum default_filter = GL_NEAREST); }; + namespace debug + { + extern std::unique_ptr g_vis_texture; + } + extern buffer g_typeless_transfer_buffer; }