GS: Add option to disable vertex shader expand

And automatically disable it on Fermi (buggy driver).
This commit is contained in:
Stenzek 2023-05-11 19:45:57 +10:00 committed by refractionpcsx2
parent 7edc4e2cb3
commit e5c1052062
11 changed files with 54 additions and 20 deletions

View File

@ -252,6 +252,7 @@ GraphicsSettingsWidget::GraphicsSettingsWidget(SettingsDialog* dialog, QWidget*
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableFramebufferFetch, "EmuCore/GS", "DisableFramebufferFetch", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableDualSource, "EmuCore/GS", "DisableDualSourceBlend", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableShaderCache, "EmuCore/GS", "DisableShaderCache", false);
SettingWidgetBinder::BindWidgetToBoolSetting(sif, m_ui.disableVertexShaderExpand, "EmuCore/GS", "DisableVertexShaderExpand", false);
SettingWidgetBinder::BindWidgetToIntSetting(
sif, m_ui.gsDownloadMode, "EmuCore/GS", "HWDownloadMode", static_cast<int>(GSHardwareDownloadMode::Enabled));

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>720</width>
<height>498</height>
<height>492</height>
</rect>
</property>
<property name="windowTitle">
@ -2146,13 +2146,6 @@
</item>
<item row="2" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QCheckBox" name="disableDualSource">
<property name="text">
<string>Disable Dual Source Blending</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="disableFramebufferFetch">
<property name="text">
@ -2160,10 +2153,10 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="useDebugDevice">
<item row="0" column="0">
<widget class="QCheckBox" name="disableDualSource">
<property name="text">
<string>Use Debug Device</string>
<string>Disable Dual Source Blending</string>
</property>
</widget>
</item>
@ -2174,6 +2167,20 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="useDebugDevice">
<property name="text">
<string>Use Debug Device</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="disableVertexShaderExpand">
<property name="text">
<string>Disable Vertex Shader Expand</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>

View File

@ -647,6 +647,7 @@ struct Pcsx2Config
DisableShaderCache : 1,
DisableDualSourceBlend : 1,
DisableFramebufferFetch : 1,
DisableVertexShaderExpand : 1,
DisableThreadedPresentation : 1,
SkipDuplicateFrames : 1,
OsdShowMessages : 1,

View File

@ -188,7 +188,7 @@ bool GSDevice11::Create()
}
}
SetFeatures();
SetFeatures(dxgi_adapter.get());
std::optional<std::string> shader = Host::ReadResourceFileToString("shaders/dx11/tfx.fx");
if (!shader.has_value())
@ -532,7 +532,7 @@ void GSDevice11::Destroy()
#endif
}
void GSDevice11::SetFeatures()
void GSDevice11::SetFeatures(IDXGIAdapter1* adapter)
{
// Check all three formats, since the feature means any can be used.
m_features.dxt_textures = SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC1_UNORM) &&
@ -542,7 +542,21 @@ void GSDevice11::SetFeatures()
m_features.bptc_textures = SupportsTextureFormat(m_dev.get(), DXGI_FORMAT_BC7_UNORM);
const D3D_FEATURE_LEVEL feature_level = m_dev->GetFeatureLevel();
m_features.vs_expand = (feature_level >= D3D_FEATURE_LEVEL_11_0);
m_features.vs_expand = (!GSConfig.DisableVertexShaderExpand && feature_level >= D3D_FEATURE_LEVEL_11_0);
// NVIDIA GPUs prior to Kepler appear to have broken vertex shader buffer loading.
if (m_features.vs_expand && (D3D::GetVendorID(adapter) == D3D::VendorID::Nvidia))
{
// There's nothing Fermi specific which we can query in DX11. Closest we have is typed UAV loads,
// which is Kepler+. Anyone using Kepler should be using Vulkan anyway.
D3D11_FEATURE_DATA_D3D11_OPTIONS2 options;
if (SUCCEEDED(m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &options, sizeof(options))) &&
!options.TypedUAVLoadAdditionalFormats)
{
Console.Warning("Disabling VS expand due to potentially buggy NVIDIA driver.");
m_features.vs_expand = false;
}
}
}
bool GSDevice11::HasSurface() const

View File

@ -118,7 +118,7 @@ private:
NUM_TIMESTAMP_QUERIES = 5,
};
void SetFeatures();
void SetFeatures(IDXGIAdapter1* adapter);
bool CreateSwapChain();
bool CreateSwapChainRTV();

View File

@ -610,7 +610,7 @@ bool GSDevice12::CheckFeatures()
m_features.clip_control = true;
m_features.stencil_buffer = true;
m_features.test_and_sample_depth = false;
m_features.vs_expand = true;
m_features.vs_expand = !GSConfig.DisableVertexShaderExpand;
m_features.dxt_textures = g_d3d12_context->SupportsTextureFormat(DXGI_FORMAT_BC1_UNORM) &&
g_d3d12_context->SupportsTextureFormat(DXGI_FORMAT_BC2_UNORM) &&

View File

@ -833,7 +833,7 @@ bool GSDeviceMTL::Create()
MTLPixelFormat layer_px_fmt = [m_layer pixelFormat];
m_features.broken_point_sampler = [[m_dev.dev name] containsString:@"AMD"];
m_features.vs_expand = true;
m_features.vs_expand = !GSConfig.DisableVertexShaderExpand;
m_features.primitive_id = m_dev.features.primid;
m_features.texture_barrier = true;
m_features.provoking_vertex_last = false;

View File

@ -159,12 +159,20 @@ bool GSDeviceOGL::Create()
m_features.stencil_buffer = true;
m_features.test_and_sample_depth = m_features.texture_barrier;
// NVIDIA GPUs prior to Kepler appear to have broken vertex shader buffer loading.
// Use bindless textures (introduced in Kepler) to differentiate.
const bool buggy_vs_expand =
GLLoader::vendor_id_nvidia && (!GLAD_GL_ARB_bindless_texture && !GLAD_GL_NV_bindless_texture);
if (buggy_vs_expand)
Console.Warning("Disabling vertex shader expand due to broken NVIDIA driver.");
if (GLAD_GL_ARB_shader_storage_buffer_object)
{
GLint max_vertex_ssbos = 0;
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &max_vertex_ssbos);
DevCon.WriteLn("GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: %d", max_vertex_ssbos);
m_features.vs_expand = (max_vertex_ssbos > 0 && GLAD_GL_ARB_gpu_shader5);
m_features.vs_expand = (!GSConfig.DisableVertexShaderExpand && !buggy_vs_expand && max_vertex_ssbos > 0 &&
GLAD_GL_ARB_gpu_shader5);
}
if (!m_features.vs_expand)
Console.Warning("Vertex expansion is not supported. This will reduce performance.");

View File

@ -696,7 +696,8 @@ bool GSDeviceVK::CheckFeatures()
m_features.provoking_vertex_last = g_vulkan_context->GetOptionalExtensions().vk_ext_provoking_vertex;
m_features.dual_source_blend = features.dualSrcBlend && !GSConfig.DisableDualSourceBlend;
m_features.clip_control = true;
m_features.vs_expand = g_vulkan_context->GetOptionalExtensions().vk_khr_shader_draw_parameters;
m_features.vs_expand =
!GSConfig.DisableVertexShaderExpand && g_vulkan_context->GetOptionalExtensions().vk_khr_shader_draw_parameters;
if (!m_features.dual_source_blend)
Console.Warning("Vulkan driver is missing dual-source blending. This will have an impact on performance.");

View File

@ -52,7 +52,6 @@ public:
bool vk_ext_line_rasterization : 1;
bool vk_ext_rasterization_order_attachment_access : 1;
bool vk_ext_full_screen_exclusive : 1;
bool vk_ext_surface_maintenance1 : 1;
bool vk_khr_driver_properties : 1;
bool vk_khr_fragment_shader_barycentric : 1;
bool vk_khr_shader_draw_parameters : 1;

View File

@ -415,6 +415,7 @@ Pcsx2Config::GSOptions::GSOptions()
UseBlitSwapChain = false;
DisableShaderCache = false;
DisableFramebufferFetch = false;
DisableVertexShaderExpand = false;
DisableThreadedPresentation = false;
SkipDuplicateFrames = false;
OsdShowMessages = true;
@ -579,6 +580,7 @@ bool Pcsx2Config::GSOptions::RestartOptionsAreEqual(const GSOptions& right) cons
OpEqu(DisableShaderCache) &&
OpEqu(DisableDualSourceBlend) &&
OpEqu(DisableFramebufferFetch) &&
OpEqu(DisableVertexShaderExpand) &&
OpEqu(DisableThreadedPresentation) &&
OpEqu(OverrideTextureBarriers) &&
OpEqu(ExclusiveFullscreenControl);
@ -634,6 +636,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
GSSettingBool(DisableShaderCache);
GSSettingBool(DisableDualSourceBlend);
GSSettingBool(DisableFramebufferFetch);
GSSettingBool(DisableVertexShaderExpand);
GSSettingBool(DisableThreadedPresentation);
GSSettingBool(SkipDuplicateFrames);
GSSettingBool(OsdShowMessages);