diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 0de8c586b6..d42512b2a2 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -194,12 +194,6 @@ void GLGSRender::begin() if (!draw_fbo.check()) return; - if (surface_clear_flags) - { - clear_surface(surface_clear_flags); - surface_clear_flags = 0; - } - std::chrono::time_point then = steady_clock::now(); bool color_mask_b = rsx::method_registers.color_mask_b(); @@ -664,9 +658,12 @@ bool GLGSRender::do_method(u32 cmd, u32 arg) switch (cmd) { case NV4097_CLEAR_SURFACE: + { init_buffers(true); - surface_clear_flags |= arg; + synchronize_buffers(); + clear_surface(arg); return true; + } case NV4097_TEXTURE_READ_SEMAPHORE_RELEASE: case NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE: flush_draw_buffers = true; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index ba879f64fd..c47eb815d1 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -89,7 +89,6 @@ private: gcm_buffer_info surface_info[rsx::limits::color_buffers_count]; gcm_buffer_info depth_surface_info; - u32 surface_clear_flags = 0; bool flush_draw_buffers = false; public: diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 7220a5be89..f2a1591191 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -153,16 +153,6 @@ namespace void GLGSRender::init_buffers(bool skip_reading) { - //NOTE 1: Sometimes, we process clear before sync flushing rsx buffers. Leads to downloading of blank data - //Clearing of surfaces is deferred to handle this - //NOTE 2: It is possible for a game to do: - //1. Bind buffer 1 - //2. Clear - //3. Bind buffer 2 without touching 1 - //4. Clear - //5. Bind buffer 1 - //6. Draw without clear - if (draw_fbo && !m_rtts_dirty) { set_viewport(); @@ -173,13 +163,6 @@ void GLGSRender::init_buffers(bool skip_reading) //LOG_WARNING(RSX, "Render targets have changed; checking for sync points (EID=%d)", m_draw_calls); synchronize_buffers(); - //If the old buffers were dirty, clear them before we bind new buffers - if (surface_clear_flags) - { - clear_surface(surface_clear_flags); - surface_clear_flags = 0; - } - m_rtts_dirty = false; const u16 clip_horizontal = rsx::method_registers.surface_clip_width(); diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index bd608f6078..9c8c61db4c 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -712,7 +712,15 @@ namespace gl return; } - verify(HERE), region->is_locked(); + if (!region->is_locked()) + { + verify(HERE), region->is_dirty(); + LOG_WARNING(RSX, "Cell write to bound render target area"); + + region->protect(0, vm::page_writable | vm::page_readable); + region->set_dirty(false); + } + region->copy_texture(); }