Skip to content

Commit 51947f8

Browse files
GS/GL: Only issue barriers for framebuffer optimizations if needed.
Check if the state changed previous draw/pass and if not then we need to issue a barrier or render pass then to ensure writes.
1 parent e07f02d commit 51947f8

File tree

3 files changed

+39
-14
lines changed

3 files changed

+39
-14
lines changed

pcsx2/GS/Renderers/OpenGL/GLState.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ namespace GLState
3636

3737
GSTextureOGL* rt = nullptr;
3838
GSTextureOGL* ds = nullptr;
39+
40+
bool rt_written;
41+
bool ds_written;
42+
3943
GLuint tex_unit[8];
4044
GLuint64 tex_handle[8];
4145

@@ -67,6 +71,10 @@ namespace GLState
6771

6872
rt = nullptr;
6973
ds = nullptr;
74+
75+
rt_written = false;
76+
ds_written = false;
77+
7078
std::fill(std::begin(tex_unit), std::end(tex_unit), 0);
7179
std::fill(std::begin(tex_handle), std::end(tex_handle), 0);
7280
}

pcsx2/GS/Renderers/OpenGL/GLState.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ namespace GLState
4040

4141
extern GSTextureOGL* rt; // render target
4242
extern GSTextureOGL* ds; // Depth-Stencil
43+
44+
extern bool rt_written; // Render Target written
45+
extern bool ds_written; // Depth Stencil written
46+
4347
extern GLuint tex_unit[8]; // shader input texture
4448
extern GLuint64 tex_handle[8]; // shader input texture
4549

pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,26 +2305,35 @@ void GSDeviceOGL::OMSetBlendState(bool enable, GLenum src_factor, GLenum dst_fac
23052305

23062306
void 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

Comments
 (0)