GS:OGL: Support disabling texture barrier

This commit is contained in:
TellowKrinkle 2022-08-31 14:51:11 -05:00 committed by tellowkrinkle
parent b96594b17c
commit 1864440f5c
3 changed files with 35 additions and 9 deletions

View File

@ -152,6 +152,7 @@ namespace GLLoader
// DX11 GPU // DX11 GPU
bool found_GL_ARB_gpu_shader5 = false; // Require IvyBridge 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_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) static bool mandatory(const std::string& ext)
{ {
@ -273,7 +274,7 @@ namespace GLLoader
optional("GL_ARB_direct_state_access"); optional("GL_ARB_direct_state_access");
// Mandatory for the advance HW renderer effect. Unfortunately Mesa LLVMPIPE/SWR renderers doesn't support this extension. // 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. // 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; 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; found_framebuffer_fetch = GLAD_GL_EXT_shader_framebuffer_fetch || GLAD_GL_ARM_shader_framebuffer_fetch;

View File

@ -45,4 +45,5 @@ namespace GLLoader
extern bool found_GL_ARB_gpu_shader5; extern bool found_GL_ARB_gpu_shader5;
extern bool found_GL_ARB_shader_image_load_store; extern bool found_GL_ARB_shader_image_load_store;
extern bool found_GL_ARB_clear_texture; extern bool found_GL_ARB_clear_texture;
extern bool found_GL_ARB_texture_barrier;
} // namespace GLLoader } // namespace GLLoader

View File

@ -218,7 +218,12 @@ bool GSDeviceOGL::Create(HostDisplay* display)
m_features.broken_point_sampler = GLLoader::vendor_id_amd; m_features.broken_point_sampler = GLLoader::vendor_id_amd;
m_features.geometry_shader = GLLoader::found_geometry_shader; 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.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.provoking_vertex_last = true;
m_features.dxt_textures = GLAD_GL_EXT_texture_compression_s3tc; 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; 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; GLState::scissor = config.scissor;
} }
GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize();
// Destination Alpha Setup // Destination Alpha Setup
switch (config.destination_alpha) switch (config.destination_alpha)
{ {
@ -1859,8 +1866,12 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
InitPrimDateTexture(config.rt, config.drawarea); InitPrimDateTexture(config.rt, config.drawarea);
break; break;
case GSHWDrawConfig::DestinationAlphaMode::StencilOne: case GSHWDrawConfig::DestinationAlphaMode::StencilOne:
ClearStencil(config.ds, 1); if (m_features.texture_barrier)
break; {
ClearStencil(config.ds, 1);
break;
}
[[fallthrough]];
case GSHWDrawConfig::DestinationAlphaMode::Stencil: case GSHWDrawConfig::DestinationAlphaMode::Stencil:
{ {
const GSVector4 src = GSVector4(config.drawarea) / GSVector4(config.ds->GetSize()).xyxy(); 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* hdr_rt = nullptr;
GSTexture* draw_rt_clone = nullptr;
if (config.ps.hdr) if (config.ps.hdr)
{ {
GSVector2i size = config.rt->GetSize(); hdr_rt = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::FloatColor, false);
hdr_rt = CreateRenderTarget(size.x, size.y, GSTexture::Format::FloatColor, false);
OMSetRenderTargets(hdr_rt, config.ds, &config.scissor); OMSetRenderTargets(hdr_rt, config.ds, &config.scissor);
// save blend state, since BlitRect destroys it // save blend state, since BlitRect destroys it
@ -1892,6 +1903,15 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
glEnable(GL_BLEND); 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(); BeginScene();
@ -1907,8 +1927,10 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config)
IASetPrimitiveTopology(topology); IASetPrimitiveTopology(topology);
PSSetShaderResources(config.tex, config.pal); PSSetShaderResources(config.tex, config.pal);
// Always bind the RT. This way special effect can use it. if (draw_rt_clone)
PSSetShaderResource(2, config.rt); PSSetShaderResource(2, draw_rt_clone);
else if (config.require_one_barrier || config.require_full_barrier)
PSSetShaderResource(2, config.rt);
SetupSampler(config.sampler); SetupSampler(config.sampler);
OMSetBlendState(config.blend.enable, s_gl_blend_factors[config.blend.src_factor], 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) if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking)
RecycleDateTexture(); RecycleDateTexture();
if (draw_rt_clone)
Recycle(draw_rt_clone);
EndScene(); 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; 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) if (config.require_full_barrier)
{ {