From 1864440f5ce9b972cb2944360165617208f03c7c Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Wed, 31 Aug 2022 14:51:11 -0500 Subject: [PATCH] GS:OGL: Support disabling texture barrier --- pcsx2/GS/Renderers/OpenGL/GLLoader.cpp | 3 +- pcsx2/GS/Renderers/OpenGL/GLLoader.h | 1 + pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp | 40 ++++++++++++++++++----- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/pcsx2/GS/Renderers/OpenGL/GLLoader.cpp b/pcsx2/GS/Renderers/OpenGL/GLLoader.cpp index ab9bb00098..9124722b15 100644 --- a/pcsx2/GS/Renderers/OpenGL/GLLoader.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GLLoader.cpp @@ -152,6 +152,7 @@ namespace GLLoader // DX11 GPU bool found_GL_ARB_gpu_shader5 = false; // Require IvyBridge bool found_GL_ARB_shader_image_load_store = false; // Intel IB. Nvidia/AMD miss Mesa implementation. + bool found_GL_ARB_texture_barrier = false; static bool mandatory(const std::string& ext) { @@ -273,7 +274,7 @@ namespace GLLoader optional("GL_ARB_direct_state_access"); // Mandatory for the advance HW renderer effect. Unfortunately Mesa LLVMPIPE/SWR renderers doesn't support this extension. // Rendering might be corrupted but it could be good enough for test/virtual machine. - optional("GL_ARB_texture_barrier"); + found_GL_ARB_texture_barrier = optional("GL_ARB_texture_barrier"); has_dual_source_blend = GLAD_GL_VERSION_3_2 || GLAD_GL_ARB_blend_func_extended; found_framebuffer_fetch = GLAD_GL_EXT_shader_framebuffer_fetch || GLAD_GL_ARM_shader_framebuffer_fetch; diff --git a/pcsx2/GS/Renderers/OpenGL/GLLoader.h b/pcsx2/GS/Renderers/OpenGL/GLLoader.h index 99fd619d18..30ff6f752c 100644 --- a/pcsx2/GS/Renderers/OpenGL/GLLoader.h +++ b/pcsx2/GS/Renderers/OpenGL/GLLoader.h @@ -45,4 +45,5 @@ namespace GLLoader extern bool found_GL_ARB_gpu_shader5; extern bool found_GL_ARB_shader_image_load_store; extern bool found_GL_ARB_clear_texture; + extern bool found_GL_ARB_texture_barrier; } // namespace GLLoader diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index 6e65fa4222..db8b4e3dcb 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -218,7 +218,12 @@ bool GSDeviceOGL::Create(HostDisplay* display) m_features.broken_point_sampler = GLLoader::vendor_id_amd; m_features.geometry_shader = GLLoader::found_geometry_shader; m_features.image_load_store = GLLoader::found_GL_ARB_shader_image_load_store && GLLoader::found_GL_ARB_clear_texture; - m_features.texture_barrier = GSConfig.OverrideTextureBarriers != 0 || GLLoader::found_framebuffer_fetch; + if (GSConfig.OverrideTextureBarriers == 0) + m_features.texture_barrier = GLLoader::found_framebuffer_fetch; // Force Disabled + else if (GSConfig.OverrideTextureBarriers == 1) + m_features.texture_barrier = true; // Force Enabled + else + m_features.texture_barrier = GLLoader::found_framebuffer_fetch || GLLoader::found_GL_ARB_texture_barrier; m_features.provoking_vertex_last = true; m_features.dxt_textures = GLAD_GL_EXT_texture_compression_s3tc; m_features.bptc_textures = GLAD_GL_VERSION_4_2 || GLAD_GL_ARB_texture_compression_bptc || GLAD_GL_EXT_texture_compression_bptc; @@ -1849,6 +1854,8 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) GLState::scissor = config.scissor; } + GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize(); + // Destination Alpha Setup switch (config.destination_alpha) { @@ -1859,8 +1866,12 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) InitPrimDateTexture(config.rt, config.drawarea); break; case GSHWDrawConfig::DestinationAlphaMode::StencilOne: - ClearStencil(config.ds, 1); - break; + if (m_features.texture_barrier) + { + ClearStencil(config.ds, 1); + break; + } + [[fallthrough]]; case GSHWDrawConfig::DestinationAlphaMode::Stencil: { const GSVector4 src = GSVector4(config.drawarea) / GSVector4(config.ds->GetSize()).xyxy(); @@ -1877,10 +1888,10 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) } GSTexture* hdr_rt = nullptr; + GSTexture* draw_rt_clone = nullptr; if (config.ps.hdr) { - GSVector2i size = config.rt->GetSize(); - hdr_rt = CreateRenderTarget(size.x, size.y, GSTexture::Format::FloatColor, false); + hdr_rt = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::FloatColor, false); OMSetRenderTargets(hdr_rt, config.ds, &config.scissor); // save blend state, since BlitRect destroys it @@ -1892,6 +1903,15 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) glEnable(GL_BLEND); } } + else if (config.require_one_barrier && !m_features.texture_barrier) + { + // Requires a copy of the RT + draw_rt_clone = CreateTexture(rtsize.x, rtsize.y, false, GSTexture::Format::Color, false); + GL_PUSH("Copy RT to temp texture for fbmask {%d,%d %dx%d}", + config.drawarea.left, config.drawarea.top, + config.drawarea.width(), config.drawarea.height()); + CopyRect(config.rt, draw_rt_clone, config.drawarea, config.drawarea.left, config.drawarea.top); + } BeginScene(); @@ -1907,8 +1927,10 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) IASetPrimitiveTopology(topology); PSSetShaderResources(config.tex, config.pal); - // Always bind the RT. This way special effect can use it. - PSSetShaderResource(2, config.rt); + if (draw_rt_clone) + PSSetShaderResource(2, draw_rt_clone); + else if (config.require_one_barrier || config.require_full_barrier) + PSSetShaderResource(2, config.rt); SetupSampler(config.sampler); OMSetBlendState(config.blend.enable, s_gl_blend_factors[config.blend.src_factor], @@ -2043,6 +2065,8 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking) RecycleDateTexture(); + if (draw_rt_clone) + Recycle(draw_rt_clone); EndScene(); @@ -2091,7 +2115,7 @@ void GSDeviceOGL::SendHWDraw(const GSHWDrawConfig& config, bool needs_barrier) } const bool tex_is_ds = config.tex && config.tex == config.ds; - if (needs_barrier || tex_is_ds) + if ((needs_barrier && m_features.texture_barrier) || tex_is_ds) { if (config.require_full_barrier) {