mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Skip unnecessary barriers (usually two pass alpha)
This commit is contained in:
parent
e8293b2e06
commit
de724d9570
|
@ -270,7 +270,9 @@ struct alignas(16) GSHWDrawConfig
|
|||
|
||||
__fi bool IsFeedbackLoop() const
|
||||
{
|
||||
return tex_is_fb || fbmask || (date > 0 && date != 3) || blend_a == 1 || blend_b == 1 || blend_c == 1 || blend_d == 1;
|
||||
const u32 sw_blend_bits = blend_a | blend_b | blend_d;
|
||||
const bool sw_blend_needs_rt = sw_blend_bits != 0 && ((sw_blend_bits | blend_c) & 1u);
|
||||
return tex_is_fb || fbmask || (date > 0 && date != 3) || sw_blend_needs_rt;
|
||||
}
|
||||
|
||||
/// Disables color output from the pixel shader, this is done when all channels are masked.
|
||||
|
|
|
@ -1959,7 +1959,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
|
||||
OMSetRenderTargets(hdr_rt ? hdr_rt : config.rt, config.ds, &config.scissor);
|
||||
|
||||
SendHWDraw(config);
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
|
||||
if (config.separate_alpha_pass)
|
||||
{
|
||||
|
@ -1969,7 +1969,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
OMSetColorMaskState(config.alpha_second_pass.colormask);
|
||||
SetupOM(config.alpha_second_pass.depth);
|
||||
OMSetBlendState();
|
||||
SendHWDraw(config);
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
|
||||
// restore blend state if we're doing a second pass
|
||||
if (config.alpha_second_pass.enable)
|
||||
|
@ -1994,7 +1994,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
SetupPipeline(psel);
|
||||
OMSetColorMaskState(config.alpha_second_pass.colormask);
|
||||
SetupOM(config.alpha_second_pass.depth);
|
||||
SendHWDraw(config);
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
|
||||
if (config.second_separate_alpha_pass)
|
||||
{
|
||||
|
@ -2004,7 +2004,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
OMSetColorMaskState(config.alpha_second_pass.colormask);
|
||||
SetupOM(config.alpha_second_pass.depth);
|
||||
OMSetBlendState();
|
||||
SendHWDraw(config);
|
||||
SendHWDraw(config, psel.ps.IsFeedbackLoop());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2026,7 +2026,7 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
|
|||
}
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config)
|
||||
void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config, bool needs_barrier)
|
||||
{
|
||||
if (config.drawlist)
|
||||
{
|
||||
|
@ -2051,31 +2051,40 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config)
|
|||
glTextureBarrier();
|
||||
DrawIndexedPrimitive(p, count);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (config.require_full_barrier)
|
||||
|
||||
const bool tex_is_ds = config.tex && config.tex == config.ds;
|
||||
if (needs_barrier || tex_is_ds)
|
||||
{
|
||||
GL_PUSH("Split the draw");
|
||||
|
||||
GL_PERF("Split single draw in %d draw", config.nindices / config.indices_per_prim);
|
||||
|
||||
for (size_t p = 0; p < config.nindices; p += config.indices_per_prim)
|
||||
if (config.require_full_barrier)
|
||||
{
|
||||
GL_PUSH("Split the draw");
|
||||
|
||||
GL_PERF("Split single draw in %d draw", config.nindices / config.indices_per_prim);
|
||||
|
||||
for (size_t p = 0; p < config.nindices; p += config.indices_per_prim)
|
||||
{
|
||||
glTextureBarrier();
|
||||
DrawIndexedPrimitive(p, config.indices_per_prim);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.require_one_barrier || tex_is_ds)
|
||||
{
|
||||
// The common renderer code doesn't put a barrier here because D3D/VK need to copy the DS, so we need to check it.
|
||||
// One barrier needed for non-overlapping draw.
|
||||
glTextureBarrier();
|
||||
DrawIndexedPrimitive(p, config.indices_per_prim);
|
||||
DrawIndexedPrimitive();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (config.require_one_barrier || (config.tex && config.tex == config.ds))
|
||||
{
|
||||
// The common renderer code doesn't put a barrier here because D3D/VK need to copy the DS, so we need to check it.
|
||||
// One barrier needed for non-overlapping draw.
|
||||
glTextureBarrier();
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
else
|
||||
{
|
||||
// No barriers needed
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
|
||||
// No barriers needed
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
|
||||
// Note: used as a callback of DebugMessageCallback. Don't change the signature
|
||||
|
|
|
@ -356,7 +356,7 @@ public:
|
|||
void StretchRect(GSTexture* sTex, const GSVector4& sRect, GSTexture* dTex, const GSVector4& dRect, const GL::Program& ps, bool alpha_blend, OMColorMaskSelector cms, bool linear = true);
|
||||
|
||||
void RenderHW(GSHWDrawConfig& config) final;
|
||||
void SendHWDraw(const GSHWDrawConfig& config);
|
||||
void SendHWDraw(const GSHWDrawConfig& config, bool needs_barrier);
|
||||
|
||||
void SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* vertices, bool datm);
|
||||
|
||||
|
|
|
@ -3152,25 +3152,33 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt)
|
|||
ColorBufferBarrier(draw_rt);
|
||||
DrawIndexedPrimitive(p, count);
|
||||
}
|
||||
}
|
||||
else if (config.require_full_barrier)
|
||||
{
|
||||
GL_PUSH("Split single draw in %d draw", config.nindices / config.indices_per_prim);
|
||||
|
||||
for (u32 p = 0; p < config.nindices; p += config.indices_per_prim)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_features.texture_barrier && m_pipeline_selector.ps.IsFeedbackLoop())
|
||||
{
|
||||
if (config.require_full_barrier)
|
||||
{
|
||||
GL_PUSH("Split single draw in %d draw", config.nindices / config.indices_per_prim);
|
||||
|
||||
for (u32 p = 0; p < config.nindices; p += config.indices_per_prim)
|
||||
{
|
||||
ColorBufferBarrier(draw_rt);
|
||||
DrawIndexedPrimitive(p, config.indices_per_prim);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.require_one_barrier)
|
||||
{
|
||||
ColorBufferBarrier(draw_rt);
|
||||
DrawIndexedPrimitive(p, config.indices_per_prim);
|
||||
DrawIndexedPrimitive();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (config.require_one_barrier && m_features.texture_barrier)
|
||||
{
|
||||
ColorBufferBarrier(draw_rt);
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't need any barrier
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
|
||||
// Don't need any barrier
|
||||
DrawIndexedPrimitive();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue