GS: Add option to disable texture barriers/geometry shaders

This commit is contained in:
Connor McLaughlin 2022-01-05 21:13:27 +10:00 committed by refractionpcsx2
parent 57ea137982
commit bb75c78c1a
11 changed files with 143 additions and 37 deletions

View File

@ -389,7 +389,13 @@ layout(set = 1, binding = 0) uniform sampler2D Texture;
layout(set = 1, binding = 1) uniform sampler2D Palette;
#if PS_FEEDBACK_LOOP_IS_NEEDED
layout(input_attachment_index = 0, set = 2, binding = 0) uniform subpassInput RtSampler;
#ifndef DISABLE_TEXTURE_BARRIER
layout(input_attachment_index = 0, set = 2, binding = 0) uniform subpassInput RtSampler;
vec4 sample_from_rt() { return subpassLoad(RtSampler); }
#else
layout(set = 2, binding = 0) uniform texture2D RtSampler;
vec4 sample_from_rt() { return texelFetch(RtSampler, ivec2(gl_FragCoord.xy), 0); }
#endif
#endif
#if PS_DATE > 0
@ -399,7 +405,7 @@ layout(set = 2, binding = 1) uniform texture2D PrimMinTexture;
vec4 sample_c(vec2 uv)
{
#if PS_TEX_IS_FB
return subpassLoad(RtSampler);
return sample_from_rt();
#else
#if PS_POINT_SAMPLER
// Weird issue with ATI/AMD cards,
@ -549,7 +555,7 @@ mat4 sample_4p(vec4 u)
int fetch_raw_depth(ivec2 xy)
{
#if PS_TEX_IS_FB
vec4 col = subpassLoad(RtSampler);
vec4 col = sample_from_rt();
#else
vec4 col = texelFetch(Texture, xy, 0);
#endif
@ -559,7 +565,7 @@ int fetch_raw_depth(ivec2 xy)
vec4 fetch_raw_color(ivec2 xy)
{
#if PS_TEX_IS_FB
return subpassLoad(RtSampler);
return sample_from_rt();
#else
return texelFetch(Texture, xy, 0);
#endif
@ -935,7 +941,7 @@ vec4 ps_color()
void ps_fbmask(inout vec4 C)
{
#if PS_FBMASK
vec4 RT = trunc(subpassLoad(RtSampler) * 255.0f + 0.1f);
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
C = vec4((uvec4(C) & ~FbMask) | (uvec4(RT) & FbMask));
#endif
}
@ -995,7 +1001,7 @@ void ps_blend(inout vec4 Color, float As)
#endif
#if PS_FEEDBACK_LOOP_IS_NEEDED
vec4 RT = trunc(subpassLoad(RtSampler) * 255.0f + 0.1f);
vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f);
#else
// Not used, but we define it to make the selection below simpler.
vec4 RT = vec4(0.0f);
@ -1095,9 +1101,9 @@ void main()
#if PS_WRITE_RG == 1
// Pseudo 16 bits access.
float rt_a = subpassLoad(RtSampler).g;
float rt_a = sample_from_rt().g;
#else
float rt_a = subpassLoad(RtSampler).a;
float rt_a = sample_from_rt().a;
#endif
#if (PS_DATE & 3) == 1

View File

@ -179,6 +179,8 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
//////////////////////////////////////////////////////////////////////////
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useBlitSwapChain, "EmuCore/GS", "UseBlitSwapChain", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.useDebugDevice, "EmuCore/GS", "UseDebugDevice", false);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overrideTextureBarriers, "EmuCore/GS", "OverrideTextureBarriers", -1, -1);
SettingWidgetBinder::BindWidgetToIntSetting(sif, m_ui.overrideGeometryShader, "EmuCore/GS", "OverrideGeometryShaders", -1, -1);
//////////////////////////////////////////////////////////////////////////
// SW Settings

View File

@ -963,21 +963,77 @@
<property name="title">
<string>Debug Options</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<layout class="QFormLayout" name="formLayout_6">
<item row="0" column="0">
<widget class="QCheckBox" name="useBlitSwapChain">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Use Blit Swap Chain</string>
<string>Override Texture Barriers:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="useDebugDevice">
<widget class="QComboBox" name="overrideTextureBarriers">
<item>
<property name="text">
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Force Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Force Enabled</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Use Debug Device</string>
<string>Override Geometry Shader:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="overrideGeometryShader">
<item>
<property name="text">
<string>Automatic (Default)</string>
</property>
</item>
<item>
<property name="text">
<string>Force Disabled</string>
</property>
</item>
<item>
<property name="text">
<string>Force Enabled</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QCheckBox" name="useBlitSwapChain">
<property name="text">
<string>Use Blit Swap Chain</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="useDebugDevice">
<property name="text">
<string>Use Debug Device</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>

View File

@ -521,6 +521,8 @@ struct Pcsx2Config
int UserHacks_TCOffsetX{0};
int UserHacks_TCOffsetY{0};
TriFiltering UserHacks_TriFilter{TriFiltering::Off};
int OverrideTextureBarriers{-1};
int OverrideGeometryShaders{-1};
int ShadeBoost_Brightness{50};
int ShadeBoost_Contrast{50};

View File

@ -14,7 +14,7 @@
#include "imgui_impl_vulkan.h"
#include <array>
static constexpr u32 SHADER_CACHE_VERSION = 1;
static constexpr u32 SHADER_CACHE_VERSION = 2;
class VulkanHostDisplayTexture : public HostDisplayTexture
{

View File

@ -1340,7 +1340,6 @@ void GSApp::Init()
m_default_configuration["OsdShowGSStats"] = "0";
m_default_configuration["OsdShowIndicators"] = "1";
m_default_configuration["OsdScale"] = "100";
m_default_configuration["override_geometry_shader"] = "-1";
m_default_configuration["override_GL_ARB_copy_image"] = "-1";
m_default_configuration["override_GL_ARB_clear_texture"] = "-1";
m_default_configuration["override_GL_ARB_clip_control"] = "-1";
@ -1351,6 +1350,8 @@ void GSApp::Init()
m_default_configuration["override_GL_ARB_sparse_texture"] = "-1";
m_default_configuration["override_GL_ARB_sparse_texture2"] = "-1";
m_default_configuration["override_GL_ARB_texture_barrier"] = "-1";
m_default_configuration["OverrideTextureBarriers"] = "-1";
m_default_configuration["OverrideGeometryShaders"] = "-1";
m_default_configuration["paltex"] = "0";
m_default_configuration["png_compression_level"] = std::to_string(Z_BEST_SPEED);
m_default_configuration["PointListPalette"] = "0";

View File

@ -216,9 +216,10 @@ namespace GLLoader
mesa_driver = !vendor_id_nvidia && !vendor_id_amd;
#endif
if (theApp.GetConfigI("override_geometry_shader") != -1)
if (GSConfig.OverrideGeometryShaders != -1)
{
found_geometry_shader = theApp.GetConfigB("override_geometry_shader");
found_geometry_shader = GSConfig.OverrideGeometryShaders != 0 &&
(GLAD_GL_VERSION_3_2 || GL_ARB_geometry_shader4 || GSConfig.OverrideGeometryShaders == 1);
GLExtension::Set("GL_ARB_geometry_shader4", found_geometry_shader);
fprintf(stderr, "Overriding geometry shaders detection\n");
}

View File

@ -217,7 +217,7 @@ 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 = true;
m_features.texture_barrier = GSConfig.OverrideTextureBarriers != 0;
m_features.provoking_vertex_last = true;
m_features.prefer_new_textures = false;
m_features.dxt_textures = GL_EXT_texture_compression_s3tc;

View File

@ -237,19 +237,18 @@ bool GSDeviceVK::CheckFeatures()
const bool isAMD = (vendorID == 0x1002 || vendorID == 0x1022);
// const bool isNVIDIA = (vendorID == 0x10DE);
m_features.texture_barrier = GSConfig.OverrideTextureBarriers != 0;
m_features.broken_point_sampler = isAMD;
m_features.geometry_shader = features.geometryShader;
m_features.image_load_store = features.fragmentStoresAndAtomics;
m_features.texture_barrier = true;
m_features.geometry_shader = features.geometryShader && GSConfig.OverrideGeometryShaders != 0;
m_features.image_load_store = features.fragmentStoresAndAtomics && m_features.texture_barrier;
m_features.prefer_new_textures = true;
m_features.provoking_vertex_last = g_vulkan_context->GetOptionalExtensions().vk_ext_provoking_vertex;
if (!features.dualSrcBlend)
{
Console.Error("Vulkan driver is missing dual-source blending.");
Host::AddOSDMessage(
"Dual-source blending is not supported by your driver. This will significantly slow performance.", 30.0f);
}
Console.Warning("Vulkan driver is missing dual-source blending. This will have an impact on performance.");
if (!m_features.texture_barrier)
Console.Warning("Texture buffers are disabled. This may break some graphical effects.");
// whether we can do point/line expand depends on the range of the device
const float f_upscale = static_cast<float>(GSConfig.UpscaleMultiplier);
@ -1036,8 +1035,9 @@ static void AddShaderHeader(std::stringstream& ss)
ss << "#version 460 core\n";
ss << "#extension GL_EXT_samplerless_texture_functions : require\n";
if (!g_vulkan_context->GetDeviceFeatures().dualSrcBlend)
ss << "#define DISABLE_DUAL_SOURCE 1\n";
const GSDevice::FeatureSupport features(g_gs_device->Features());
if (!features.texture_barrier)
ss << "#define DISABLE_TEXTURE_BARRIER 1\n";
}
static void AddShaderStageMacro(std::stringstream& ss, bool vs, bool gs, bool fs)
@ -1170,7 +1170,7 @@ bool GSDeviceVK::CreatePipelineLayouts()
if ((m_tfx_sampler_ds_layout = dslb.Create(dev)) == VK_NULL_HANDLE)
return false;
Vulkan::Util::SetObjectName(dev, m_tfx_sampler_ds_layout, "TFX sampler descriptor layout");
dslb.AddBinding(0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
dslb.AddBinding(0, m_features.texture_barrier ? VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
dslb.AddBinding(1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
if ((m_tfx_rt_texture_ds_layout = dslb.Create(dev)) == VK_NULL_HANDLE)
return false;
@ -2412,7 +2412,10 @@ bool GSDeviceVK::ApplyTFXState(bool already_execed)
return ApplyTFXState(true);
}
dsub.AddInputAttachmentDescriptorWrite(ds, 0, m_tfx_textures[NUM_TFX_SAMPLERS]);
if (m_features.texture_barrier)
dsub.AddInputAttachmentDescriptorWrite(ds, 0, m_tfx_textures[NUM_TFX_SAMPLERS]);
else
dsub.AddImageDescriptorWrite(ds, 0, m_tfx_textures[NUM_TFX_SAMPLERS]);
dsub.AddImageDescriptorWrite(ds, 1, m_tfx_textures[NUM_TFX_SAMPLERS + 1]);
dsub.Update(dev);
@ -2718,6 +2721,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
GSTextureVK* draw_rt = static_cast<GSTextureVK*>(config.rt);
GSTextureVK* draw_ds = static_cast<GSTextureVK*>(config.ds);
GSTextureVK* draw_rt_clone = nullptr;
GSTextureVK* hdr_rt = nullptr;
GSTextureVK* copy_ds = nullptr;
@ -2747,8 +2751,29 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
draw_rt->TransitionToLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
}
// we're not drawing to the RT, so we can use it as a source
if (config.require_one_barrier && !m_features.texture_barrier)
PSSetShaderResource(2, draw_rt, true);
draw_rt = hdr_rt;
}
else if (config.require_one_barrier && !m_features.texture_barrier)
{
// requires a copy of the RT
draw_rt_clone = static_cast<GSTextureVK*>(CreateTexture(rtsize.x, rtsize.y, false, GSTexture::Format::Color, true));
if (draw_rt_clone)
{
EndRenderPass();
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());
DoCopyRect(draw_rt, draw_rt_clone, config.drawarea, config.drawarea);
draw_rt_clone->TransitionToLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
PSSetShaderResource(2, draw_rt_clone, false);
}
}
if (config.tex && config.tex == config.ds)
{
@ -2790,7 +2815,10 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
OMSetRenderTargets(draw_rt, draw_ds, config.scissor, pipe.feedback_loop);
if (pipe.feedback_loop)
{
pxAssertMsg(m_features.texture_barrier, "Texture barriers enabled");
PSSetShaderResource(2, draw_rt, false);
}
// Begin render pass if new target or out of the area.
if (!render_area_okay || !InRenderPass())
@ -2866,6 +2894,9 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
if (copy_ds)
Recycle(copy_ds);
if (draw_rt_clone)
Recycle(draw_rt_clone);
if (date_image)
Recycle(date_image);
@ -2929,9 +2960,9 @@ void GSDeviceVK::UpdateHWPipelineSelector(GSHWDrawConfig& config)
m_pipeline_selector.rt = config.rt != nullptr;
m_pipeline_selector.ds = config.ds != nullptr;
m_pipeline_selector.line_width = config.line_expand;
m_pipeline_selector.feedback_loop =
config.ps.IsFeedbackLoop() || config.require_one_barrier || config.require_full_barrier ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking;
m_pipeline_selector.feedback_loop = m_features.texture_barrier &&
(config.ps.IsFeedbackLoop() || config.require_one_barrier || config.require_full_barrier ||
config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking);
// enable point size in the vertex shader if we're rendering points regardless of upscaling.
m_pipeline_selector.vs.point_size |= (config.topology == GSHWDrawConfig::Topology::Point);
@ -2960,7 +2991,7 @@ void GSDeviceVK::SendHWDraw(const GSHWDrawConfig& config, GSTextureVK* draw_rt)
DrawIndexedPrimitive(p, config.indices_per_prim);
}
}
else if (config.require_one_barrier)
else if (config.require_one_barrier && m_features.texture_barrier)
{
ColorBufferBarrier(draw_rt);
DrawIndexedPrimitive();

View File

@ -566,9 +566,10 @@ DebugTab::DebugTab(wxWindow* parent)
tab_box->Add(debug_box.outer, wxSizerFlags().Expand());
}
PaddedBoxSizer<wxStaticBoxSizer> ogl_box(wxVERTICAL, this, "OpenGL");
PaddedBoxSizer<wxStaticBoxSizer> ogl_box(wxVERTICAL, this, "Overrides");
auto* ogl_grid = new wxFlexGridSizer(2, space, space);
m_ui.addComboBoxAndLabel(ogl_grid, "Geometry Shader:", "override_geometry_shader", &theApp.m_gs_generic_list, IDC_GEOMETRY_SHADER_OVERRIDE, ogl_hw_prereq);
m_ui.addComboBoxAndLabel(ogl_grid, "Texture Barriers:", "OverrideTextureBarriers", &theApp.m_gs_generic_list, -1);
m_ui.addComboBoxAndLabel(ogl_grid, "Geometry Shader:", "OverrideGeometryShaders", &theApp.m_gs_generic_list, IDC_GEOMETRY_SHADER_OVERRIDE);
m_ui.addComboBoxAndLabel(ogl_grid, "Image Load Store:", "override_GL_ARB_shader_image_load_store", &theApp.m_gs_generic_list, IDC_IMAGE_LOAD_STORE, ogl_hw_prereq);
m_ui.addComboBoxAndLabel(ogl_grid, "Sparse Texture:", "override_GL_ARB_sparse_texture", &theApp.m_gs_generic_list, IDC_SPARSE_TEXTURE, ogl_hw_prereq);
ogl_box->Add(ogl_grid);

View File

@ -396,6 +396,8 @@ bool Pcsx2Config::GSOptions::OptionsAreEqual(const GSOptions& right) const
OpEqu(UserHacks_TCOffsetX) &&
OpEqu(UserHacks_TCOffsetY) &&
OpEqu(UserHacks_TriFilter) &&
OpEqu(OverrideTextureBarriers) &&
OpEqu(OverrideGeometryShaders) &&
OpEqu(ShadeBoost_Brightness) &&
OpEqu(ShadeBoost_Contrast) &&
@ -419,7 +421,9 @@ bool Pcsx2Config::GSOptions::RestartOptionsAreEqual(const GSOptions& right) cons
OpEqu(UseDebugDevice) &&
OpEqu(UseBlitSwapChain) &&
OpEqu(DisableShaderCache) &&
OpEqu(ThreadedPresentation);
OpEqu(ThreadedPresentation) &&
OpEqu(OverrideTextureBarriers) &&
OpEqu(OverrideGeometryShaders);
}
void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
@ -568,6 +572,8 @@ void Pcsx2Config::GSOptions::ReloadIniSettings()
GSSettingIntEx(UserHacks_TCOffsetX, "UserHacks_TCOffsetX");
GSSettingIntEx(UserHacks_TCOffsetY, "UserHacks_TCOffsetY");
GSSettingIntEnumEx(UserHacks_TriFilter, "UserHacks_TriFilter");
GSSettingIntEx(OverrideTextureBarriers, "OverrideTextureBarriers");
GSSettingIntEx(OverrideGeometryShaders, "OverrideGeometryShaders");
GSSettingInt(ShadeBoost_Brightness);
GSSettingInt(ShadeBoost_Contrast);