From 732de53d1b3120b5b979048fc0493c2909050bd3 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 21 Dec 2021 17:41:50 +1000 Subject: [PATCH] GS: Get rid of second constant buffer for alpha pass --- pcsx2/GS/Renderers/Common/GSDevice.h | 2 +- pcsx2/GS/Renderers/DX11/GSDevice11.cpp | 12 ++++++- pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp | 2 +- pcsx2/GS/Renderers/HW/GSRendererNew.cpp | 28 ++++++++------- pcsx2/GS/Renderers/HW/GSRendererNew.h | 2 +- pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp | 43 ++++++++++------------- pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h | 2 -- 7 files changed, 48 insertions(+), 43 deletions(-) diff --git a/pcsx2/GS/Renderers/Common/GSDevice.h b/pcsx2/GS/Renderers/Common/GSDevice.h index 91d8f284e1..199a1c1375 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.h +++ b/pcsx2/GS/Renderers/Common/GSDevice.h @@ -485,7 +485,7 @@ struct GSHWDrawConfig ColorMaskSelector colormask; DepthStencilSelector depth; PSSelector ps; - PSConstantBuffer cb_ps; + float ps_aref; } alpha_second_pass; }; diff --git a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp index 23913e565b..7c26b07bf7 100644 --- a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp @@ -1583,7 +1583,17 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config) if (config.alpha_second_pass.enable) { preprocessSel(config.alpha_second_pass.ps); - SetupPS(config.alpha_second_pass.ps, &config.alpha_second_pass.cb_ps, config.sampler); + if (config.cb_ps.FogColor_AREF.a != config.alpha_second_pass.ps_aref) + { + config.cb_ps.FogColor_AREF.a = config.alpha_second_pass.ps_aref; + SetupPS(config.alpha_second_pass.ps, &config.cb_ps, config.sampler); + } + else + { + // ps cbuffer hasn't changed, so don't bother checking + SetupPS(config.alpha_second_pass.ps, nullptr, config.sampler); + } + SetupOM(config.alpha_second_pass.depth, convertSel(config.alpha_second_pass.colormask, config.blend), config.blend.factor); DrawIndexedPrimitive(); diff --git a/pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp b/pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp index f5ebb2dcbd..2574013d38 100644 --- a/pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSTextureFX11.cpp @@ -196,7 +196,7 @@ void GSDevice11::SetupPS(PSSelector sel, const GSHWDrawConfig::PSConstantBuffer* i = m_ps.try_emplace(sel.key, std::move(ps)).first; } - if (m_ps_cb_cache.Update(*cb)) + if (cb && m_ps_cb_cache.Update(*cb)) { m_ctx->UpdateSubresource(m_ps_cb.get(), 0, NULL, cb, 0, 0); } diff --git a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp index 289a88186c..29d3ecb1c6 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp @@ -1099,7 +1099,7 @@ GSRendererNew::PRIM_OVERLAP GSRendererNew::PrimitiveOverlap() return overlap; } -void GSRendererNew::EmulateATST(GSHWDrawConfig::PSConstantBuffer& cb, GSHWDrawConfig::PSSelector& ps, bool pass_2) +void GSRendererNew::EmulateATST(float& AREF, GSHWDrawConfig::PSSelector& ps, bool pass_2) { static const u32 inverted_atst[] = {ATST_ALWAYS, ATST_NEVER, ATST_GEQUAL, ATST_GREATER, ATST_NOTEQUAL, ATST_LESS, ATST_LEQUAL, ATST_EQUAL}; @@ -1113,27 +1113,27 @@ void GSRendererNew::EmulateATST(GSHWDrawConfig::PSConstantBuffer& cb, GSHWDrawCo switch (atst) { case ATST_LESS: - cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f; + AREF = (float)m_context->TEST.AREF - 0.1f; ps.atst = 1; break; case ATST_LEQUAL: - cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f; + AREF = (float)m_context->TEST.AREF - 0.1f + 1.0f; ps.atst = 1; break; case ATST_GEQUAL: - cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f; + AREF = (float)m_context->TEST.AREF - 0.1f; ps.atst = 2; break; case ATST_GREATER: - cb.FogColor_AREF.a = (float)m_context->TEST.AREF - 0.1f + 1.0f; + AREF = (float)m_context->TEST.AREF - 0.1f + 1.0f; ps.atst = 2; break; case ATST_EQUAL: - cb.FogColor_AREF.a = (float)m_context->TEST.AREF; + AREF = (float)m_context->TEST.AREF; ps.atst = 3; break; case ATST_NOTEQUAL: - cb.FogColor_AREF.a = (float)m_context->TEST.AREF; + AREF = (float)m_context->TEST.AREF; ps.atst = 4; break; case ATST_NEVER: // Draw won't be done so no need to implement it in shader @@ -1441,7 +1441,12 @@ void GSRendererNew::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour } else { - EmulateATST(m_conf.cb_ps, m_conf.ps, false); + float aref = m_conf.cb_ps.FogColor_AREF.a; + EmulateATST(aref, m_conf.ps, false); + + // avoid redundant cbuffer updates + m_conf.cb_ps.FogColor_AREF.a = aref; + m_conf.alpha_second_pass.ps_aref = aref; } if (tex) @@ -1507,7 +1512,6 @@ void GSRendererNew::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour if (ate_second_pass) { ASSERT(!m_env.PABE.PABE); - memcpy(&m_conf.alpha_second_pass.cb_ps, &m_conf.cb_ps, sizeof(m_conf.cb_ps)); memcpy(&m_conf.alpha_second_pass.ps, &m_conf.ps, sizeof(m_conf.ps)); memcpy(&m_conf.alpha_second_pass.colormask, &m_conf.colormask, sizeof(m_conf.colormask)); memcpy(&m_conf.alpha_second_pass.depth, &m_conf.depth, sizeof(m_conf.depth)); @@ -1516,13 +1520,13 @@ void GSRendererNew::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour { // Enable ATE as first pass to update the depth // of pixels that passed the alpha test - EmulateATST(m_conf.alpha_second_pass.cb_ps, m_conf.alpha_second_pass.ps, false); + EmulateATST(m_conf.alpha_second_pass.ps_aref, m_conf.alpha_second_pass.ps, false); } else { // second pass will process the pixels that failed // the alpha test - EmulateATST(m_conf.alpha_second_pass.cb_ps, m_conf.alpha_second_pass.ps, true); + EmulateATST(m_conf.alpha_second_pass.ps_aref, m_conf.alpha_second_pass.ps, true); } @@ -1575,10 +1579,10 @@ void GSRendererNew::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour return; // RenderHW always renders first pass, replace first pass with second - memcpy(&m_conf.cb_ps, &m_conf.alpha_second_pass.cb_ps, sizeof(m_conf.cb_ps)); memcpy(&m_conf.ps, &m_conf.alpha_second_pass.ps, sizeof(m_conf.ps)); memcpy(&m_conf.colormask, &m_conf.alpha_second_pass.colormask, sizeof(m_conf.colormask)); memcpy(&m_conf.depth, &m_conf.alpha_second_pass.depth, sizeof(m_conf.depth)); + m_conf.cb_ps.FogColor_AREF.a = m_conf.alpha_second_pass.ps_aref; m_conf.alpha_second_pass.enable = false; } diff --git a/pcsx2/GS/Renderers/HW/GSRendererNew.h b/pcsx2/GS/Renderers/HW/GSRendererNew.h index 32bded65cc..d54df3b96d 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererNew.h +++ b/pcsx2/GS/Renderers/HW/GSRendererNew.h @@ -43,7 +43,7 @@ private: inline void EmulateBlending(bool& DATE_GL42, bool& DATE_GL45); inline void EmulateTextureSampler(const GSTextureCache::Source* tex); inline void EmulateZbuffer(); - inline void EmulateATST(GSHWDrawConfig::PSConstantBuffer& cb, GSHWDrawConfig::PSSelector& ps, bool pass_2); + inline void EmulateATST(float& AREF, GSHWDrawConfig::PSSelector& ps, bool pass_2); public: GSRendererNew(); diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index afe7afea07..f3791a6439 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -1907,29 +1907,6 @@ __fi static void WriteToStreamBuffer(GL::StreamBuffer* sb, u32 index, u32 align, glBindBufferRange(GL_UNIFORM_BUFFER, index, sb->GetGLBufferId(), res.buffer_offset, size); } -void GSDeviceOGL::SetupCB(const GSHWDrawConfig::VSConstantBuffer* vs_cb, const GSHWDrawConfig::PSConstantBuffer* ps_cb) -{ - GL_PUSH("UBO"); - - if (m_vs_cb_cache.Update(*vs_cb)) - { - WriteToStreamBuffer(m_vertex_uniform_stream_buffer.get(), g_vs_cb_index, - m_uniform_buffer_alignment, vs_cb, sizeof(GSHWDrawConfig::VSConstantBuffer)); - } - - if (m_ps_cb_cache.Update(*ps_cb)) - { - WriteToStreamBuffer(m_fragment_uniform_stream_buffer.get(), g_ps_cb_index, - m_uniform_buffer_alignment, ps_cb, sizeof(GSHWDrawConfig::PSConstantBuffer)); - } -} - -void GSDeviceOGL::SetupCBMisc(const GSVector4i& channel) -{ - m_misc_cb_cache.ChannelShuffle = channel; - m_convert.cb->cache_upload(&m_misc_cb_cache); -} - void GSDeviceOGL::SetupPipeline(const VSSelector& vsel, const GSSelector& gsel, const PSSelector& psel) { auto i = m_ps.find(psel.key); @@ -2099,7 +2076,16 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) OMSetColorMaskState(config.colormask); SetupOM(config.depth); - SetupCB(&config.cb_vs, &config.cb_ps); + if (m_vs_cb_cache.Update(config.cb_vs)) + { + WriteToStreamBuffer(m_vertex_uniform_stream_buffer.get(), g_vs_cb_index, + m_uniform_buffer_alignment, &config.cb_vs, sizeof(config.cb_vs)); + } + if (m_ps_cb_cache.Update(config.cb_ps)) + { + WriteToStreamBuffer(m_fragment_uniform_stream_buffer.get(), g_ps_cb_index, + m_uniform_buffer_alignment, &config.cb_ps, sizeof(config.cb_ps)); + } GSSelector gssel; if (config.gs.expand) @@ -2153,7 +2139,14 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) if (config.alpha_second_pass.enable) { - SetupCB(&config.cb_vs, &config.alpha_second_pass.cb_ps); + // cbuffer will definitely be dirty if aref changes, no need to check it + if (config.cb_ps.FogColor_AREF.a != config.alpha_second_pass.ps_aref) + { + config.cb_ps.FogColor_AREF.a = config.alpha_second_pass.ps_aref; + WriteToStreamBuffer(m_fragment_uniform_stream_buffer.get(), g_ps_cb_index, + m_uniform_buffer_alignment, &config.cb_ps, sizeof(config.cb_ps)); + } + SetupPipeline(vssel, gssel, config.alpha_second_pass.ps); OMSetColorMaskState(config.alpha_second_pass.colormask); SetupOM(config.alpha_second_pass.depth); diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h index 04a063f394..e2085c252f 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.h @@ -379,8 +379,6 @@ public: void SelfShaderTest(); void SetupPipeline(const VSSelector& vsel, const GSSelector& gsel, const PSSelector& psel); - void SetupCB(const GSHWDrawConfig::VSConstantBuffer* vs_cb, const GSHWDrawConfig::PSConstantBuffer* ps_cb); - void SetupCBMisc(const GSVector4i& channel); void SetupSampler(PSSamplerSelector ssel); void SetupOM(OMDepthStencilSelector dssel); GLuint GetSamplerID(PSSamplerSelector ssel);