diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index e4c0407395..2676a12b35 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1414,19 +1414,22 @@ void GLGSRender::do_local_task(bool /*idle*/) std::lock_guard lock(queue_guard); - work_queue.remove_if([](work_item &q) { return q.received; }); - - for (work_item& q: work_queue) + if (!work_queue.empty()) { - if (q.processed) continue; + work_queue.remove_if([](work_item &q) { return q.received; }); - std::unique_lock lock(q.guard_mutex); - q.result = m_gl_texture_cache.flush_all(q.section_data); - q.processed = true; + for (work_item& q : work_queue) + { + if (q.processed) continue; - //Notify thread waiting on this - lock.unlock(); - q.cv.notify_one(); + std::unique_lock lock(q.guard_mutex); + q.result = m_gl_texture_cache.flush_all(q.section_data); + q.processed = true; + + //Notify thread waiting on this + lock.unlock(); + q.cv.notify_one(); + } } if (m_overlay_cleanup_requests.size()) diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.cpp b/rpcs3/Emu/RSX/GL/GLHelpers.cpp index e892f72c31..9a0322d6dd 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.cpp +++ b/rpcs3/Emu/RSX/GL/GLHelpers.cpp @@ -296,6 +296,16 @@ namespace gl m_id = id; } + void fbo::set_extents(size2i extents) + { + m_size = extents; + } + + size2i fbo::get_extents() const + { + return m_size; + } + void texture::settings::apply(const texture &texture) const { save_binding_state save(texture); diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index a15fdae4b6..4d8d21aedf 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -1921,6 +1921,7 @@ namespace gl class fbo { GLuint m_id = GL_NONE; + size2i m_size; public: fbo() = default; @@ -1939,17 +1940,23 @@ namespace gl class save_binding_state { GLint m_last_binding; + bool reset = true; public: save_binding_state(const fbo& new_binding) { glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_last_binding); - new_binding.bind(); + + if (m_last_binding != new_binding.id()) + new_binding.bind(); + else + reset = false; } ~save_binding_state() { - glBindFramebuffer(GL_FRAMEBUFFER, m_last_binding); + if (reset) + glBindFramebuffer(GL_FRAMEBUFFER, m_last_binding); } }; @@ -2093,6 +2100,9 @@ namespace gl GLuint id() const; void set_id(GLuint id); + void set_extents(size2i extents); + size2i get_extents() const; + explicit operator bool() const { return created(); diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 5799128196..15d845a87c 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -223,7 +223,7 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool sk if (lg2w > 0 || lg2h > 0) { //Something was actually declared for the swizzle context dimensions - LOG_ERROR(RSX, "Invalid swizzled context depth surface dims, LG2W=%d, LG2H=%d, clip_w=%d, clip_h=%d", lg2w, lg2h, clip_horizontal, clip_vertical); + LOG_WARNING(RSX, "Invalid swizzled context depth surface dims, LG2W=%d, LG2H=%d, clip_w=%d, clip_h=%d", lg2w, lg2h, clip_horizontal, clip_vertical); } } else @@ -244,7 +244,7 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool sk if (lg2w > 0 || lg2h > 0) { //Something was actually declared for the swizzle context dimensions - LOG_ERROR(RSX, "Invalid swizzled context color surface dims, LG2W=%d, LG2H=%d, clip_w=%d, clip_h=%d", lg2w, lg2h, clip_horizontal, clip_vertical); + LOG_WARNING(RSX, "Invalid swizzled context color surface dims, LG2W=%d, LG2H=%d, clip_w=%d, clip_h=%d", lg2w, lg2h, clip_horizontal, clip_vertical); } } else @@ -284,10 +284,39 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool sk return; } + if (draw_fbo) + { + bool really_changed = false; + auto sz = draw_fbo.get_extents(); + + if (sz.width == clip_horizontal && sz.height == clip_vertical) + { + for (u8 i = 0; i < rsx::limits::color_buffers_count; ++i) + { + if (m_surface_info[i].address != surface_addresses[i]) + { + really_changed = true; + break; + } + } + + if (!really_changed) + { + if (depth_address == m_depth_surface_info.address) + { + //Nothing has changed, we're still using the same framebuffer + return; + } + } + } + } + m_rtts.prepare_render_target(nullptr, surface_format, depth_format, clip_horizontal, clip_vertical, target, surface_addresses, depth_address); draw_fbo.recreate(); + draw_fbo.bind(); + draw_fbo.set_extents({ (int)clip_horizontal, (int)clip_vertical }); bool old_format_found = false; gl::texture::format old_format; @@ -360,8 +389,6 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool sk if (!framebuffer_status_valid) return; check_zcull_status(true, false); - - draw_fbo.bind(); set_viewport(); switch (rsx::method_registers.surface_color_target()) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index beb0fac695..8a1ec9679f 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2521,7 +2521,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context) if (lg2w > 0 || lg2h > 0) { //Something was actually declared for the swizzle context dimensions - LOG_ERROR(RSX, "Invalid swizzled context depth surface dims, LG2W=%d, LG2H=%d, clip_w=%d, clip_h=%d", lg2w, lg2h, clip_width, clip_height); + LOG_WARNING(RSX, "Invalid swizzled context depth surface dims, LG2W=%d, LG2H=%d, clip_w=%d, clip_h=%d", lg2w, lg2h, clip_width, clip_height); } } else @@ -2542,7 +2542,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context) if (lg2w > 0 || lg2h > 0) { //Something was actually declared for the swizzle context dimensions - LOG_ERROR(RSX, "Invalid swizzled context color surface dims, LG2W=%d, LG2H=%d, clip_w=%d, clip_h=%d", lg2w, lg2h, clip_width, clip_height); + LOG_WARNING(RSX, "Invalid swizzled context color surface dims, LG2W=%d, LG2H=%d, clip_w=%d, clip_h=%d", lg2w, lg2h, clip_width, clip_height); } } else @@ -2594,7 +2594,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context) { bool really_changed = false; - if (m_draw_fbo->width() == fbo_width && m_draw_fbo->height() == clip_height) + if (m_draw_fbo->width() == fbo_width && m_draw_fbo->height() == fbo_height) { for (u8 i = 0; i < rsx::limits::color_buffers_count; ++i) {