@@ -2305,26 +2305,35 @@ void GSDeviceOGL::OMSetBlendState(bool enable, GLenum src_factor, GLenum dst_fac
23052305
23062306void GSDeviceOGL::OMSetRenderTargets (GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
23072307{
2308- g_perfmon.Put (GSPerfMon::RenderPasses, static_cast <double >(GLState::rt != rt || GLState::ds != ds));
2308+ const bool rt_changed = (rt != GLState::rt);
2309+ const bool ds_changed = (ds != GLState::ds);
23092310
2311+ g_perfmon.Put (GSPerfMon::RenderPasses, static_cast <double >(rt_changed || ds_changed));
23102312 // Split up to avoid unbind/bind calls when clearing.
23112313
23122314 OMSetFBO (m_fbo);
2315+
2316+ GLState::rt_written = false ;
2317+ GLState::ds_written = false ;
2318+
23132319 if (rt)
2320+ {
23142321 OMAttachRt (rt);
2322+ CommitClear (rt, false );
2323+ GLState::rt_written = rt_changed;
2324+ }
23152325 else
23162326 OMAttachRt ();
23172327
23182328 if (ds)
2329+ {
23192330 OMAttachDs (ds);
2331+ CommitClear (ds, false );
2332+ GLState::ds_written = ds_changed;
2333+ }
23202334 else
23212335 OMAttachDs ();
23222336
2323- if (rt)
2324- CommitClear (rt, false );
2325- if (ds)
2326- CommitClear (ds, false );
2327-
23282337 if (rt || ds)
23292338 {
23302339 const GSVector2i size = rt ? rt->GetSize () : ds->GetSize ();
@@ -2578,14 +2587,6 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
25782587 if (config.require_one_barrier || !m_features.texture_barrier )
25792588 rt_hazard_barrier = false ; // Already in place or not available
25802589
2581- // Be careful of the rt already being bound and the blend using the RT without a barrier.
2582- if (rt_hazard_barrier)
2583- {
2584- // Ensure all depth writes are finished before sampling
2585- GL_INS (" GL: Texture barrier to flush depth or rt before reading" );
2586- g_perfmon.Put (GSPerfMon::Barriers, 1 );
2587- glTextureBarrier ();
2588- }
25892590 // additional non-pipeline config stuff
25902591 const bool point_size_enabled = config.vs .point_size ;
25912592 if (GLState::point_size != point_size_enabled)
@@ -2644,15 +2645,27 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
26442645 // avoid changing framebuffer just to switch from rt+depth to rt and vice versa
26452646 GSTexture* draw_rt = colclip_rt ? colclip_rt : config.rt ;
26462647 GSTexture* draw_ds = config.ds ;
2648+ bool fb_optimization_needs_barrier = false ;
26472649 if (!draw_rt && GLState::rt && GLState::ds == draw_ds && config.tex != GLState::rt &&
26482650 GLState::rt->GetSize () == draw_ds->GetSize ())
26492651 {
26502652 draw_rt = GLState::rt;
2653+ fb_optimization_needs_barrier = !GLState::rt_written;
26512654 }
26522655 else if (!draw_ds && GLState::ds && GLState::rt == draw_rt && config.tex != GLState::ds &&
26532656 GLState::ds->GetSize () == draw_rt->GetSize ())
26542657 {
26552658 draw_ds = GLState::ds;
2659+ fb_optimization_needs_barrier = !GLState::ds_written;
2660+ }
2661+
2662+ // Be careful of the rt already being bound and the blend using the RT without a barrier.
2663+ if (fb_optimization_needs_barrier && rt_hazard_barrier)
2664+ {
2665+ // Ensure all depth writes are finished before sampling
2666+ GL_INS (" GL: Texture barrier to flush depth or rt before reading" );
2667+ g_perfmon.Put (GSPerfMon::Barriers, 1 );
2668+ glTextureBarrier ();
26562669 }
26572670
26582671 OMSetRenderTargets (draw_rt, draw_ds, &config.scissor );
0 commit comments