summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2018-03-16 23:10:22 +1000
committerStenzek <stenzek@gmail.com>2018-03-26 01:57:41 +1000
commit2f1a7cbee1ffecdd25ebc206ceab55ef934b7256 (patch)
tree1cbf78b64fbf293ede3a9bd47e586a0d4bb03a6b
parent5c83e18fbd3606587e71a7f1cc54e4cf6473609f (diff)
Implement "Skip" ubershader mode
Skip ubershader mode works the same as hybrid ubershaders in that the shaders are compiled asynchronously. However, instead of using the ubershader to draw the object, it skips it entirely until the specialized shader is made available. This mode will likely result in broken effects where a game creates an EFB copy, and does not redraw it every frame. Therefore, it is not a recommended option, however, it may result in better performance on low-end systems.
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsFragmentPresenter.java10
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/SettingsFile.java3
-rw-r--r--Source/Android/app/src/main/res/values/arrays.xml12
-rw-r--r--Source/Android/app/src/main/res/values/strings.xml5
-rw-r--r--Source/Core/Core/Analytics.cpp21
-rw-r--r--Source/Core/Core/Config/GraphicsSettings.cpp5
-rw-r--r--Source/Core/Core/Config/GraphicsSettings.h2
-rw-r--r--Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp5
-rw-r--r--Source/Core/DolphinQt2/CMakeLists.txt1
-rw-r--r--Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp16
-rw-r--r--Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h1
-rw-r--r--Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp59
-rw-r--r--Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h3
-rw-r--r--Source/Core/DolphinQt2/Config/Graphics/GraphicsRadio.cpp24
-rw-r--r--Source/Core/DolphinQt2/Config/Graphics/GraphicsRadio.h26
-rw-r--r--Source/Core/DolphinQt2/DolphinQt2.vcxproj3
-rw-r--r--Source/Core/DolphinWX/VideoConfigDiag.cpp100
-rw-r--r--Source/Core/DolphinWX/VideoConfigDiag.h46
-rw-r--r--Source/Core/VideoBackends/Vulkan/VertexManager.cpp19
-rw-r--r--Source/Core/VideoCommon/VertexManagerBase.cpp36
-rw-r--r--Source/Core/VideoCommon/VideoConfig.cpp9
-rw-r--r--Source/Core/VideoCommon/VideoConfig.h13
22 files changed, 292 insertions, 127 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsFragmentPresenter.java
index 11ad71a9cf..3caeaa514b 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsFragmentPresenter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/settings/SettingsFragmentPresenter.java
@@ -259,10 +259,14 @@ public final class SettingsFragmentPresenter
{
IntSetting videoBackend = new IntSetting(SettingsFile.KEY_VIDEO_BACKEND_INDEX, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, getVideoBackendValue());
Setting showFps = null;
+ Setting shaderCompilationMode = null;
+ Setting waitForShaders = null;
if (!mSettings.get(SettingsFile.SETTINGS_GFX).isEmpty())
{
showFps = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_SHOW_FPS);
+ shaderCompilationMode = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_SHADER_COMPILATION_MODE);
+ waitForShaders = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_WAIT_FOR_SHADERS);
}
else
{
@@ -276,6 +280,8 @@ public final class SettingsFragmentPresenter
sl.add(new SingleChoiceSetting(SettingsFile.KEY_VIDEO_BACKEND_INDEX, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.video_backend, R.string.video_backend_descrip, R.array.videoBackendEntries, R.array.videoBackendValues, 0, videoBackend));
sl.add(new CheckBoxSetting(SettingsFile.KEY_SHOW_FPS, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.show_fps, 0, false, showFps));
+ sl.add(new SingleChoiceSetting(SettingsFile.KEY_SHADER_COMPILATION_MODE, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.shader_compilation_mode, R.string.shader_compilation_mode_descrip, R.array.shaderCompilationModeEntries, R.array.shaderCompilationModeValues, 0, shaderCompilationMode));
+ sl.add(new CheckBoxSetting(SettingsFile.KEY_WAIT_FOR_SHADERS, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.wait_for_shaders, 0, false, waitForShaders));
sl.add(new SubmenuSetting(null, null, R.string.enhancements, 0, SettingsFile.SECTION_GFX_ENHANCEMENTS));
sl.add(new SubmenuSetting(null, null, R.string.hacks, 0, SettingsFile.SECTION_GFX_HACKS));
@@ -290,7 +296,8 @@ public final class SettingsFragmentPresenter
Setting perPixel = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_PER_PIXEL);
Setting forceFilter = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_FORCE_FILTERING);
Setting disableFog = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_DISABLE_FOG);
- Setting uberShaderMode = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_UBERSHADER_MODE);
+ Setting shaderCompilationMode = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_SHADER_COMPILATION_MODE);
+ Setting waitForShaders = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_WAIT_FOR_SHADERS);
sl.add(new SingleChoiceSetting(SettingsFile.KEY_INTERNAL_RES, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.internal_resolution, R.string.internal_resolution_descrip, R.array.internalResolutionEntries, R.array.internalResolutionValues, 0, resolution));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_FSAA, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.FSAA, R.string.FSAA_descrip, R.array.FSAAEntries, R.array.FSAAValues, 0, fsaa));
@@ -304,7 +311,6 @@ public final class SettingsFragmentPresenter
sl.add(new CheckBoxSetting(SettingsFile.KEY_PER_PIXEL, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.per_pixel_lighting, R.string.per_pixel_lighting_descrip, false, perPixel));
sl.add(new CheckBoxSetting(SettingsFile.KEY_FORCE_FILTERING, SettingsFile.SECTION_GFX_ENHANCEMENTS, SettingsFile.SETTINGS_GFX, R.string.force_texture_filtering, R.string.force_texture_filtering_descrip, false, forceFilter));
sl.add(new CheckBoxSetting(SettingsFile.KEY_DISABLE_FOG, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.disable_fog, R.string.disable_fog_descrip, false, disableFog));
- sl.add(new SingleChoiceSetting(SettingsFile.KEY_UBERSHADER_MODE, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.ubershader_mode, R.string.ubershader_mode_descrip, R.array.uberShaderModeEntries, R.array.uberShaderModeValues, 0, uberShaderMode));
/*
Check if we support stereo
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/SettingsFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/SettingsFile.java
index 3e5a1586a3..34d4e2fa71 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/SettingsFile.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/SettingsFile.java
@@ -107,7 +107,8 @@ public final class SettingsFile
public static final String KEY_IMMEDIATE_XFB = "ImmediateXFBEnable";
public static final String KEY_FAST_DEPTH = "FastDepthCalc";
public static final String KEY_ASPECT_RATIO = "AspectRatio";
- public static final String KEY_UBERSHADER_MODE = "UberShaderMode";
+ public static final String KEY_SHADER_COMPILATION_MODE = "ShaderCompilationMode";
+ public static final String KEY_WAIT_FOR_SHADERS = "WaitForShadersBeforeStarting";
public static final String KEY_GCPAD_TYPE = "SIDevice";
diff --git a/Source/Android/app/src/main/res/values/arrays.xml b/Source/Android/app/src/main/res/values/arrays.xml
index ce9c4a542c..c9d6f9a414 100644
--- a/Source/Android/app/src/main/res/values/arrays.xml
+++ b/Source/Android/app/src/main/res/values/arrays.xml
@@ -92,15 +92,17 @@
</integer-array>
<!-- Ubershader Mode Preference -->
- <string-array name="uberShaderModeEntries" translatable="false">
- <item>Disabled</item>
- <item>Hybrid</item>
- <item>Exclusive</item>
+ <string-array name="shaderCompilationModeEntries" translatable="false">
+ <item>Synchronous</item>
+ <item>Synchronous (Ubershaders)</item>
+ <item>Asynchronous (Ubershaders)</item>
+ <item>Asynchronous (Skip Drawing)</item>
</string-array>
- <integer-array name="uberShaderModeValues" translatable="false">
+ <integer-array name="shaderCompilationModeValues" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
+ <item>3</item>
</integer-array>
<!-- Internal Resolution Preference -->
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index c975edad91..ea7edcfbcd 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -184,8 +184,9 @@
<string name="fast_depth_calculation_descrip">Uses a less accurate algorithm to calculate depth values.</string>
<string name="aspect_ratio">Aspect Ratio</string>
<string name="aspect_ratio_descrip">Select what aspect ratio to use when rendering</string>
- <string name="ubershader_mode">Ubershader Mode</string>
- <string name="ubershader_mode_descrip">Specifies when to use Ubershaders. Disabled - Never, Hybrid - Use ubershaders while compiling specialized shaders. Exclusive - Use only ubershaders, largest performance impact.</string>
+ <string name="shader_compilation_mode">Shader Compilation Mode</string>
+ <string name="shader_compilation_mode_descrip">Specifies when to use Ubershaders. Disabled - Never, Hybrid - Use ubershaders while compiling specialized shaders. Exclusive - Use only ubershaders, largest performance impact. Skip Drawing - Do not draw objects while shaders are compiling, will cause broken effects.</string>
+ <string name="wait_for_shaders">Compile Shaders Before Starting</string>
<!-- Miscellaneous -->
<string name="yes">Yes</string>
diff --git a/Source/Core/Core/Analytics.cpp b/Source/Core/Core/Analytics.cpp
index db881d61de..6c45c1e400 100644
--- a/Source/Core/Core/Analytics.cpp
+++ b/Source/Core/Core/Analytics.cpp
@@ -178,17 +178,19 @@ void DolphinAnalytics::MakeBaseBuilder()
m_base_builder = builder;
}
-static const char* GetUbershaderMode(const VideoConfig& video_config)
+static const char* GetShaderCompilationMode(const VideoConfig& video_config)
{
- switch (video_config.iUberShaderMode)
+ switch (video_config.iShaderCompilationMode)
{
- case UberShaderMode::Exclusive:
- return "exclusive";
- case UberShaderMode::Hybrid:
- return "hybrid";
- case UberShaderMode::Disabled:
+ case ShaderCompilationMode::AsynchronousUberShaders:
+ return "async-ubershaders";
+ case ShaderCompilationMode::AsynchronousSkipRendering:
+ return "async-skip-rendering";
+ case ShaderCompilationMode::SynchronousUberShaders:
+ return "sync-ubershaders";
+ case ShaderCompilationMode::Synchronous:
default:
- return "disabled";
+ return "sync";
}
}
@@ -234,7 +236,8 @@ void DolphinAnalytics::MakePerGameBuilder()
builder.AddData("cfg-gfx-tc-samples", g_Config.iSafeTextureCache_ColorSamples);
builder.AddData("cfg-gfx-stereo-mode", static_cast<int>(g_Config.stereo_mode));
builder.AddData("cfg-gfx-per-pixel-lighting", g_Config.bEnablePixelLighting);
- builder.AddData("cfg-gfx-ubershader-mode", GetUbershaderMode(g_Config));
+ builder.AddData("cfg-gfx-shader-compilation-mode", GetShaderCompilationMode(g_Config));
+ builder.AddData("cfg-gfx-wait-for-shaders", g_Config.bWaitForShadersBeforeStarting);
builder.AddData("cfg-gfx-fast-depth", g_Config.bFastDepthCalc);
builder.AddData("cfg-gfx-vertex-rounding", g_Config.UseVertexRounding());
diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp
index 10a70c6020..7412c81740 100644
--- a/Source/Core/Core/Config/GraphicsSettings.cpp
+++ b/Source/Core/Core/Config/GraphicsSettings.cpp
@@ -78,8 +78,9 @@ const ConfigInfo<int> GFX_COMMAND_BUFFER_EXECUTE_INTERVAL{
const ConfigInfo<bool> GFX_SHADER_CACHE{{System::GFX, "Settings", "ShaderCache"}, true};
const ConfigInfo<bool> GFX_WAIT_FOR_SHADERS_BEFORE_STARTING{
{System::GFX, "Settings", "WaitForShadersBeforeStarting"}, false};
-const ConfigInfo<int> GFX_UBERSHADER_MODE{{System::GFX, "Settings", "UberShaderMode"},
- static_cast<int>(UberShaderMode::Disabled)};
+const ConfigInfo<int> GFX_SHADER_COMPILATION_MODE{
+ {System::GFX, "Settings", "ShaderCompilationMode"},
+ static_cast<int>(ShaderCompilationMode::Synchronous)};
const ConfigInfo<int> GFX_SHADER_COMPILER_THREADS{
{System::GFX, "Settings", "ShaderCompilerThreads"}, 1};
const ConfigInfo<int> GFX_SHADER_PRECOMPILER_THREADS{
diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h
index 5c1684777b..999192c578 100644
--- a/Source/Core/Core/Config/GraphicsSettings.h
+++ b/Source/Core/Core/Config/GraphicsSettings.h
@@ -60,7 +60,7 @@ extern const ConfigInfo<bool> GFX_BACKEND_MULTITHREADING;
extern const ConfigInfo<int> GFX_COMMAND_BUFFER_EXECUTE_INTERVAL;
extern const ConfigInfo<bool> GFX_SHADER_CACHE;
extern const ConfigInfo<bool> GFX_WAIT_FOR_SHADERS_BEFORE_STARTING;
-extern const ConfigInfo<int> GFX_UBERSHADER_MODE;
+extern const ConfigInfo<int> GFX_SHADER_COMPILATION_MODE;
extern const ConfigInfo<int> GFX_SHADER_COMPILER_THREADS;
extern const ConfigInfo<int> GFX_SHADER_PRECOMPILER_THREADS;
diff --git a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
index ef71c085ab..d9e210deaa 100644
--- a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
+++ b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
@@ -46,8 +46,9 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location)
Config::GFX_DISABLE_FOG.location, Config::GFX_BORDERLESS_FULLSCREEN.location,
Config::GFX_ENABLE_VALIDATION_LAYER.location, Config::GFX_BACKEND_MULTITHREADING.location,
Config::GFX_COMMAND_BUFFER_EXECUTE_INTERVAL.location, Config::GFX_SHADER_CACHE.location,
- Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING.location, Config::GFX_UBERSHADER_MODE.location,
- Config::GFX_SHADER_COMPILER_THREADS.location, Config::GFX_SHADER_PRECOMPILER_THREADS.location,
+ Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING.location,
+ Config::GFX_SHADER_COMPILATION_MODE.location, Config::GFX_SHADER_COMPILER_THREADS.location,
+ Config::GFX_SHADER_PRECOMPILER_THREADS.location,
Config::GFX_SW_ZCOMPLOC.location, Config::GFX_SW_ZFREEZE.location,
Config::GFX_SW_DUMP_OBJECTS.location, Config::GFX_SW_DUMP_TEV_STAGES.location,
diff --git a/Source/Core/DolphinQt2/CMakeLists.txt b/Source/Core/DolphinQt2/CMakeLists.txt
index 52af9c951d..d00bc5ee1a 100644
--- a/Source/Core/DolphinQt2/CMakeLists.txt
+++ b/Source/Core/DolphinQt2/CMakeLists.txt
@@ -45,6 +45,7 @@ set(SRCS
Config/Graphics/HacksWidget.cpp
Config/Graphics/GraphicsBool.cpp
Config/Graphics/GraphicsChoice.cpp
+ Config/Graphics/GraphicsRadio.cpp
Config/Graphics/GraphicsSlider.cpp
Config/Graphics/GraphicsWidget.cpp
Config/Graphics/GraphicsWindow.cpp
diff --git a/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp
index b6baa9819f..06f611f5d1 100644
--- a/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp
+++ b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.cpp
@@ -63,9 +63,6 @@ void EnhancementsWidget::CreateWidgets()
m_af_combo = new GraphicsChoice({tr("1x"), tr("2x"), tr("4x"), tr("8x"), tr("16x")},
Config::GFX_ENHANCE_MAX_ANISOTROPY);
- m_ubershader_combo = new GraphicsChoice({tr("Disabled"), tr("Hybrid"), tr("Exclusive")},
- Config::GFX_UBERSHADER_MODE);
-
m_pp_effect = new QComboBox();
m_configure_pp_effect = new QPushButton(tr("Configure"));
m_scaled_efb_copy = new GraphicsBool(tr("Scaled EFB Copy"), Config::GFX_HACK_COPY_EFB_SCALED);
@@ -85,9 +82,6 @@ void EnhancementsWidget::CreateWidgets()
enhancements_layout->addWidget(new QLabel(tr("Anisotropic Filtering:")), 2, 0);
enhancements_layout->addWidget(m_af_combo, 2, 1, 1, -1);
- enhancements_layout->addWidget(new QLabel(tr("Ubershaders:")), 3, 0);
- enhancements_layout->addWidget(m_ubershader_combo, 3, 1, 1, -1);
-
enhancements_layout->addWidget(new QLabel(tr("Post-Processing Effect:")), 4, 0);
enhancements_layout->addWidget(m_pp_effect, 4, 1);
enhancements_layout->addWidget(m_configure_pp_effect, 4, 2);
@@ -243,15 +237,6 @@ void EnhancementsWidget::AddDescriptions()
"Enable anisotropic filtering.\nEnhances visual quality of textures that are at oblique "
"viewing angles.\nMight cause issues in a small number of games.\n\nIf unsure, select 1x.");
- static const char* TR_UBERSHADER_DESCRIPTION =
- QT_TR_NOOP("Disabled: Ubershaders are never used. Stuttering will occur during shader "
- "compilation, but GPU demands are low. Recommended for low-end hardware.\n\n"
- "Hybrid: Ubershaders will be used to prevent stuttering during shader "
- "compilation, but traditional shaders will be used when they will not cause "
- "stuttering. Balances performance and smoothness.\n\n"
- "Exclusive: Ubershaders will always be used. Only recommended for high-end "
- "systems.");
-
static const char* TR_POSTPROCESSING_DESCRIPTION = QT_TR_NOOP(
"Apply a post-processing effect after finishing a frame.\n\nIf unsure, select (off).");
@@ -303,7 +288,6 @@ void EnhancementsWidget::AddDescriptions()
AddDescription(m_ir_combo, TR_INTERNAL_RESOLUTION_DESCRIPTION);
AddDescription(m_aa_combo, TR_ANTIALIAS_DESCRIPTION);
AddDescription(m_af_combo, TR_ANISOTROPIC_FILTERING_DESCRIPTION);
- AddDescription(m_ubershader_combo, TR_UBERSHADER_DESCRIPTION);
AddDescription(m_pp_effect, TR_POSTPROCESSING_DESCRIPTION);
AddDescription(m_scaled_efb_copy, TR_SCALED_EFB_COPY_DESCRIPTION);
AddDescription(m_per_pixel_lighting, TR_PER_PIXEL_LIGHTING_DESCRIPTION);
diff --git a/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h
index fd5b20a1b4..ac23ed84e9 100644
--- a/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h
+++ b/Source/Core/DolphinQt2/Config/Graphics/EnhancementsWidget.h
@@ -30,7 +30,6 @@ private:
QComboBox* m_ir_combo;
QComboBox* m_aa_combo;
QComboBox* m_af_combo;
- QComboBox* m_ubershader_combo;
QComboBox* m_pp_effect;
QPushButton* m_configure_pp_effect;
QCheckBox* m_scaled_efb_copy;
diff --git a/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp
index 21281488b8..1542ae535a 100644
--- a/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp
+++ b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.cpp
@@ -11,6 +11,7 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QMessageBox>
+#include <QRadioButton>
#include <QVBoxLayout>
#include "Core/Config/GraphicsSettings.h"
@@ -18,6 +19,7 @@
#include "Core/Core.h"
#include "DolphinQt2/Config/Graphics/GraphicsBool.h"
#include "DolphinQt2/Config/Graphics/GraphicsChoice.h"
+#include "DolphinQt2/Config/Graphics/GraphicsRadio.h"
#include "DolphinQt2/Config/Graphics/GraphicsWindow.h"
#include "DolphinQt2/Settings.h"
#include "UICommon/VideoUtils.h"
@@ -87,8 +89,6 @@ void GeneralWidget::CreateWidgets()
m_keep_window_top = new QCheckBox(tr("Keep Window on Top"));
m_hide_cursor = new QCheckBox(tr("Hide Mouse Cursor"));
m_render_main_window = new QCheckBox(tr("Render to Main Window"));
- m_wait_for_shaders = new GraphicsBool(tr("Immediately Compile Shaders"),
- Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING);
m_options_box->setLayout(m_options_layout);
@@ -103,10 +103,30 @@ void GeneralWidget::CreateWidgets()
m_options_layout->addWidget(m_hide_cursor, 3, 0);
m_options_layout->addWidget(m_render_main_window, 3, 1);
- m_options_layout->addWidget(m_wait_for_shaders, 4, 0);
+
+ // Other
+ auto* shader_compilation_box = new QGroupBox(tr("Shader Compilation"));
+ auto* shader_compilation_layout = new QGridLayout();
+
+ const std::array<const char*, 4> modes = {{
+ "Synchronous", "Synchronous (Ubershaders)", "Asynchronous (Ubershaders)",
+ "Asynchronous (Skip Drawing)",
+ }};
+ for (size_t i = 0; i < modes.size(); i++)
+ {
+ m_shader_compilation_mode[i] = new GraphicsRadioInt(
+ tr(modes[i]), Config::GFX_SHADER_COMPILATION_MODE, static_cast<int>(i));
+ shader_compilation_layout->addWidget(m_shader_compilation_mode[i], static_cast<int>(i / 2),
+ static_cast<int>(i % 2));
+ }
+ m_wait_for_shaders = new GraphicsBool(tr("Compile Shaders Before Starting"),
+ Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING);
+ shader_compilation_layout->addWidget(m_wait_for_shaders);
+ shader_compilation_box->setLayout(shader_compilation_layout);
main_layout->addWidget(m_video_box);
main_layout->addWidget(m_options_box);
+ main_layout->addWidget(shader_compilation_box);
main_layout->addStretch();
setLayout(main_layout);
@@ -268,12 +288,27 @@ void GeneralWidget::AddDescriptions()
static const char* TR_SHOW_NETPLAY_MESSAGES_DESCRIPTION =
QT_TR_NOOP("When playing on NetPlay, show chat messages, buffer changes and "
"desync alerts.\n\nIf unsure, leave this unchecked.");
- static const char* TR_WAIT_FOR_SHADERS_DESCRIPTION = QT_TR_NOOP(
- "Waits for all shaders to finish compiling before starting a game. Enabling this "
- "option may reduce stuttering or hitching for a short time after the game is "
- "started, at the cost of a longer delay before the game starts.\n\nFor systems "
- "with two or fewer cores, it is recommended to enable this option, as a large "
- "shader queue may reduce frame rates. Otherwise, if unsure, leave this unchecked.");
+ static const char* TR_SHADER_COMPILE_SYNC_DESCRIPTION =
+ QT_TR_NOOP("Ubershaders are never used. Stuttering will occur during shader "
+ "compilation, but GPU demands are low. Recommended for low-end hardware.\n\nIf "
+ "unsure, select this mode.");
+ static const char* TR_SHADER_COMPILE_UBER_ONLY_DESCRIPTION =
+ QT_TR_NOOP("Ubershaders will always be used. Provides a near stutter-free experience at the "
+ "cost of high GPU requirements. Only recommended for high-end systems.");
+ static const char* TR_SHADER_COMPILE_ASYNC_UBER_DESCRIPTION =
+ QT_TR_NOOP("Ubershaders will be used to prevent stuttering during shader compilation, but "
+ "specialized shaders will be used when they will not cause stuttering.");
+ static const char* TR_SHADER_COMPILE_ASYNC_SKIP_DESCRIPTION =
+ QT_TR_NOOP("Instead of using ubershaders during shader compilation, objects which use these "
+ "shaders will be not be rendered. This can further reduce stuttering and "
+ "performance requirements, compared to ubershaders, at the cost of introducing "
+ "visual glitches and broken effects. Not recommended.");
+ static const char* TR_SHADER_COMPILE_BEFORE_START_DESCRIPTION =
+ QT_TR_NOOP("Waits for all shaders to finish compiling before starting a game. Enabling this "
+ "option may reduce stuttering or hitching for a short time after the game is "
+ "started, at the cost of a longer delay before the game starts. For systems with "
+ "two or fewer cores, it is recommended to enable this option, as a large shader "
+ "queue may reduce frame rates. Otherwise, if unsure, leave this unchecked.");
AddDescription(m_backend_combo, TR_BACKEND_DESCRIPTION);
#ifdef _WIN32
@@ -291,7 +326,11 @@ void GeneralWidget::AddDescriptions()
AddDescription(m_show_messages, TR_SHOW_FPS_DESCRIPTION);
AddDescription(m_keep_window_top, TR_KEEP_WINDOW_ON_TOP_DESCRIPTION);
AddDescription(m_show_messages, TR_SHOW_NETPLAY_MESSAGES_DESCRIPTION);
- AddDescription(m_wait_for_shaders, TR_WAIT_FOR_SHADERS_DESCRIPTION);
+ AddDescription(m_shader_compilation_mode[0], TR_SHADER_COMPILE_SYNC_DESCRIPTION);
+ AddDescription(m_shader_compilation_mode[1], TR_SHADER_COMPILE_UBER_ONLY_DESCRIPTION);
+ AddDescription(m_shader_compilation_mode[2], TR_SHADER_COMPILE_ASYNC_UBER_DESCRIPTION);
+ AddDescription(m_shader_compilation_mode[3], TR_SHADER_COMPILE_ASYNC_SKIP_DESCRIPTION);
+ AddDescription(m_wait_for_shaders, TR_SHADER_COMPILE_BEFORE_START_DESCRIPTION);
}
void GeneralWidget::OnBackendChanged(const QString& backend_name)
{
diff --git a/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h
index 8b2d22f331..b8dd799649 100644
--- a/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h
+++ b/Source/Core/DolphinQt2/Config/Graphics/GeneralWidget.h
@@ -4,11 +4,13 @@
#pragma once
+#include <array>
#include "DolphinQt2/Config/Graphics/GraphicsWidget.h"
class GraphicsWindow;
class QCheckBox;
class QComboBox;
+class QRadioButton;
class QGridLayout;
namespace X11Utils
@@ -52,6 +54,7 @@ private:
QCheckBox* m_keep_window_top;
QCheckBox* m_hide_cursor;
QCheckBox* m_render_main_window;
+ std::array<QRadioButton*, 4> m_shader_compilation_mode{};
QCheckBox* m_wait_for_shaders;
X11Utils::XRRConfiguration* m_xrr_config;
diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsRadio.cpp b/Source/Core/DolphinQt2/Config/Graphics/GraphicsRadio.cpp
new file mode 100644
index 0000000000..c8f87a548b
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsRadio.cpp
@@ -0,0 +1,24 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/Config/Graphics/GraphicsRadio.h"
+
+#include "Common/Config/Config.h"
+#include "DolphinQt2/Settings.h"
+
+GraphicsRadioInt::GraphicsRadioInt(const QString& label, const Config::ConfigInfo<int>& setting,
+ int value)
+ : QRadioButton(label), m_setting(setting), m_value(value)
+{
+ setChecked(Config::Get(m_setting) == m_value);
+ connect(this, &QRadioButton::toggled, this, &GraphicsRadioInt::Update);
+}
+
+void GraphicsRadioInt::Update()
+{
+ if (!isChecked())
+ return;
+
+ Config::SetBaseOrCurrent(m_setting, m_value);
+}
diff --git a/Source/Core/DolphinQt2/Config/Graphics/GraphicsRadio.h b/Source/Core/DolphinQt2/Config/Graphics/GraphicsRadio.h
new file mode 100644
index 0000000000..dde18704ee
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/Graphics/GraphicsRadio.h
@@ -0,0 +1,26 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QRadioButton>
+
+namespace Config
+{
+template <typename T>
+struct ConfigInfo;
+}
+
+class GraphicsRadioInt : public QRadioButton
+{
+ Q_OBJECT
+public:
+ GraphicsRadioInt(const QString& label, const Config::ConfigInfo<int>& setting, int value);
+
+private:
+ void Update();
+
+ const Config::ConfigInfo<int>& m_setting;
+ int m_value;
+};
diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
index 3fe5e2613d..a87fa822cd 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
@@ -79,6 +79,7 @@
<QtMoc Include="Config\Graphics\GeneralWidget.h" />
<QtMoc Include="Config\Graphics\GraphicsBool.h" />
<QtMoc Include="Config\Graphics\GraphicsChoice.h" />
+ <QtMoc Include="Config\Graphics\GraphicsRadio.h" />
<QtMoc Include="Config\Graphics\GraphicsSlider.h" />
<QtMoc Include="Config\Graphics\GraphicsWidget.h" />
<QtMoc Include="Config\Graphics\GraphicsWindow.h" />
@@ -161,6 +162,7 @@
<ClCompile Include="$(QtMocOutPrefix)GeneralWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsBool.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsChoice.cpp" />
+ <ClCompile Include="$(QtMocOutPrefix)GraphicsRadio.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsSlider.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GraphicsWindow.cpp" />
@@ -212,6 +214,7 @@
<ClCompile Include="Config\Graphics\GeneralWidget.cpp" />
<ClCompile Include="Config\Graphics\GraphicsBool.cpp" />
<ClCompile Include="Config\Graphics\GraphicsChoice.cpp" />
+ <ClCompile Include="Config\Graphics\GraphicsRadio.cpp" />
<ClCompile Include="Config\Graphics\GraphicsSlider.cpp" />
<ClCompile Include="Config\Graphics\GraphicsWidget.cpp" />
<ClCompile Include="Config\Graphics\GraphicsWindow.cpp" />
diff --git a/Source/Core/DolphinWX/VideoConfigDiag.cpp b/Source/Core/DolphinWX/VideoConfigDiag.cpp
index cdebfd27e9..ec6a434b8b 100644
--- a/Source/Core/DolphinWX/VideoConfigDiag.cpp
+++ b/Source/Core/DolphinWX/VideoConfigDiag.cpp
@@ -44,7 +44,6 @@
// template instantiation
template class BoolSetting<wxCheckBox>;
-template class BoolSetting<wxRadioButton>;
template <>
SettingCheckBox::BoolSetting(wxWindow* parent, const wxString& label, const wxString& tooltip,
@@ -60,19 +59,6 @@ SettingCheckBox::BoolSetting(wxWindow* parent, const wxString& label, const wxSt
}
template <>
-SettingRadioButton::BoolSetting(wxWindow* parent, const wxString& label, const wxString& tooltip,
- const Config::ConfigInfo<bool>& setting, bool reverse, long style)
- : wxRadioButton(parent, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, style),
- m_setting(setting), m_reverse(reverse)
-{
- SetToolTip(tooltip);
- SetValue(Config::Get(m_setting) ^ m_reverse);
- if (Config::GetActiveLayerForConfig(m_setting) != Config::LayerType::Base)
- SetFont(GetFont().MakeBold());
- Bind(wxEVT_RADIOBUTTON, &SettingRadioButton::UpdateValue, this);
-}
-
-template <>
RefBoolSetting<wxCheckBox>::RefBoolSetting(wxWindow* parent, const wxString& label,
const wxString& tooltip, bool& setting, bool reverse,
long style)
@@ -311,18 +297,35 @@ static wxString gpu_texture_decoding_desc =
"bottleneck.\n\nIf unsure, leave this unchecked.");
static wxString ubershader_desc =
wxTRANSLATE("Disabled: Ubershaders are never used. Stuttering will occur during shader "
- "compilation, but GPU demands are low. Recommended for low-end hardware.\n\n"
+ "compilation, but GPU demands are low. Recommended for low-end hardware.\n"
"Hybrid: Ubershaders will be used to prevent stuttering during shader "
"compilation, but traditional shaders will be used when they will not cause "
- "stuttering. Balances performance and smoothness.\n\n"
+ "stuttering. Balances performance and smoothness.\n"
"Exclusive: Ubershaders will always be used. Only recommended for high-end "
- "systems.");
-static wxString wait_for_shaders_desc =
+ "systems.\n"
+ "Skip Drawing: Does not draw objects during shader compilation. Reduces "
+ "stuttering at the cost of missing objects, or broken effects.");
+static wxString shader_compile_sync_desc =
+ wxTRANSLATE("Ubershaders are never used. Stuttering will occur during shader "
+ "compilation, but GPU demands are low. Recommended for low-end hardware.\n\nIf "
+ "unsure, select this mode.");
+static wxString shader_compile_uber_only_desc =
+ wxTRANSLATE("Ubershaders will always be used. Provides a near stutter-free experience at the "
+ "cost of high GPU requirements. Only recommended for high-end systems.");
+static wxString shader_compile_async_uber_desc =
+ wxTRANSLATE("Ubershaders will be used to prevent stuttering during shader compilation, but "
+ "specialized shaders will be used when they will not cause stuttering.");
+static wxString shader_compile_async_skip_desc =
+ wxTRANSLATE("Instead of using ubershaders during shader compilation, objects which use these "
+ "shaders will be not be rendered. This can further reduce stuttering and "
+ "performance requirements, compared to ubershaders, at the cost of introducing "
+ "visual glitches and broken effects. Not recommended.");
+static wxString shader_compile_before_start_desc =
wxTRANSLATE("Waits for all shaders to finish compiling before starting a game. Enabling this "
"option may reduce stuttering or hitching for a short time after the game is "
- "started, at the cost of a longer delay before the game starts.\n\nFor systems "
- "with two or fewer cores, it is recommended to enable this option, as a large "
- "shader queue may reduce frame rates. Otherwise, if unsure, leave this unchecked.");
+ "started, at the cost of a longer delay before the game starts. For systems with "
+ "two or fewer cores, it is recommended to enable this option, as a large shader "
+ "queue may reduce frame rates. Otherwise, if unsure, leave this unchecked.");
VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title)
: wxDialog(parent, wxID_ANY, wxString::Format(_("Dolphin %s Graphics Configuration"),
@@ -448,10 +451,29 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title)
wxGetTranslation(backend_multithreading_desc),
Config::GFX_BACKEND_MULTITHREADING));
}
+ }
- szr_other->Add(CreateCheckBox(page_general, _("Immediately Compile Shaders"),
- wxGetTranslation(wait_for_shaders_desc),
- Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING));
+ // - shader compilation
+ wxGridBagSizer* const szr_shader_compilation = new wxGridBagSizer(space5, space5);
+ {
+ const std::array<std::pair<wxString, wxString>, 4> modes = {
+ {{_("Synchronous"), wxGetTranslation(shader_compile_sync_desc)},
+ {_("Synchronous (Ubershaders)"), wxGetTranslation(shader_compile_uber_only_desc)},
+ {_("Asynchronous (Ubershaders)"), wxGetTranslation(shader_compile_async_uber_desc)},
+ {_("Asynchronous (Skip Drawing)"), wxGetTranslation(shader_compile_async_skip_desc)}}};
+ for (size_t i = 0; i < modes.size(); i++)
+ {
+ szr_shader_compilation->Add(
+ CreateRadioButton(page_general, modes[i].first, modes[i].second,
+ Config::GFX_SHADER_COMPILATION_MODE, static_cast<int>(i)),
+ wxGBPosition(static_cast<int>(i / 2), static_cast<int>(i % 2)), wxDefaultSpan,
+ wxALIGN_CENTER_VERTICAL);
+ }
+ szr_shader_compilation->Add(
+ CreateCheckBox(page_general, _("Compile Shaders Before Starting"),
+ wxGetTranslation(shader_compile_before_start_desc),
+ Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING),
+ wxGBPosition(2, 0), wxGBSpan(1, 2));
}
wxStaticBoxSizer* const group_basic =
@@ -469,12 +491,19 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title)
group_other->Add(szr_other, 1, wxEXPAND | wxLEFT | wxRIGHT, space5);
group_other->AddSpacer(space5);
+ wxStaticBoxSizer* const group_shader_compilation =
+ new wxStaticBoxSizer(wxVERTICAL, page_general, _("Shader Compilation"));
+ group_shader_compilation->Add(szr_shader_compilation, 1, wxEXPAND | wxLEFT | wxRIGHT, space5);
+ group_shader_compilation->AddSpacer(space5);
+
szr_general->AddSpacer(space5);
szr_general->Add(group_basic, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
szr_general->AddSpacer(space5);
szr_general->Add(group_display, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
szr_general->AddSpacer(space5);
szr_general->Add(group_other, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
+ szr_general->AddSpacer(space5);
+ szr_general->Add(group_shader_compilation, 0, wxEXPAND | wxLEFT | wxRIGHT, space5);
}
szr_general->AddSpacer(space5);
@@ -541,18 +570,6 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title)
row += 1;
}
- // ubershaders
- {
- const std::array<wxString, 3> mode_choices = {{_("Disabled"), _("Hybrid"), _("Exclusive")}};
- szr_enh->Add(new wxStaticText(page_enh, wxID_ANY, _("Ubershaders:")), wxGBPosition(row, 0),
- wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
- szr_enh->Add(CreateChoice(page_enh, Config::GFX_UBERSHADER_MODE,
- wxGetTranslation(ubershader_desc), mode_choices.size(),
- mode_choices.data()),
- wxGBPosition(row, 1), span2, wxALIGN_CENTER_VERTICAL);
- row += 1;
- }
-
// postproc shader
if (vconfig.backend_info.bSupportsPostProcessing)
{
@@ -1111,17 +1128,6 @@ SettingChoice* VideoConfigDiag::CreateChoice(wxWindow* parent,
return ch;
}
-SettingRadioButton* VideoConfigDiag::CreateRadioButton(wxWindow* parent, const wxString& label,
- const wxString& description,
- const Config::ConfigInfo<bool>& setting,
- bool reverse, long style)
-{
- SettingRadioButton* const rb =
- new SettingRadioButton(parent, label, wxString(), setting, reverse, style);
- RegisterControl(rb, description);
- return rb;
-}
-
/* Use this to register descriptions for controls which have NOT been created using the Create*
* functions from above */
wxControl* VideoConfigDiag::RegisterControl(wxControl* const control, const wxString& description)
diff --git a/Source/Core/DolphinWX/VideoConfigDiag.h b/Source/Core/DolphinWX/VideoConfigDiag.h
index a15472885a..af3cccc4cb 100644
--- a/Source/Core/DolphinWX/VideoConfigDiag.h
+++ b/Source/Core/DolphinWX/VideoConfigDiag.h
@@ -64,7 +64,6 @@ private:
};
typedef BoolSetting<wxCheckBox> SettingCheckBox;
-typedef BoolSetting<wxRadioButton> SettingRadioButton;
class IntegerSetting : public wxSpinCtrl
{
@@ -93,6 +92,33 @@ private:
Config::ConfigInfo<int> m_setting;
};
+template <typename ValueType>
+class SettingRadioButton : public wxRadioButton
+{
+public:
+ SettingRadioButton(wxWindow* parent, const wxString& label, const wxString& tooltip,
+ const Config::ConfigInfo<ValueType>& setting, const ValueType& value,
+ long style = 0)
+ : wxRadioButton(parent, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, style),
+ m_setting(setting), m_value(value)
+ {
+ SetToolTip(tooltip);
+ SetValue(Config::Get(m_setting) == m_value);
+ Bind(wxEVT_RADIOBUTTON, &SettingRadioButton::UpdateValue, this);
+ }
+
+ void UpdateValue(wxCommandEvent& ev)
+ {
+ if (ev.IsChecked())
+ Config::SetBaseOrCurrent(m_setting, m_value);
+ ev.Skip();
+ }
+
+private:
+ Config::ConfigInfo<ValueType> m_setting;
+ ValueType m_value;
+};
+
class VideoConfigDiag : public wxDialog
{
public:
@@ -125,10 +151,17 @@ protected:
SettingChoice* CreateChoice(wxWindow* parent, const Config::ConfigInfo<int>& setting,
const wxString& description, int num = 0,
const wxString choices[] = nullptr, long style = 0);
- SettingRadioButton* CreateRadioButton(wxWindow* parent, const wxString& label,
- const wxString& description,
- const Config::ConfigInfo<bool>& setting,
- bool reverse = false, long style = 0);
+ template <typename ValueType>
+ SettingRadioButton<ValueType>* CreateRadioButton(wxWindow* parent, const wxString& label,
+ const wxString& description,
+ const Config::ConfigInfo<ValueType>& setting,
+ const ValueType& value, long style = 0)
+ {
+ auto* const rb =
+ new SettingRadioButton<ValueType>(parent, label, wxString(), setting, value, style);
+ RegisterControl(rb, description);
+ return rb;
+ }
// Same as above but only connects enter/leave window events
wxControl* RegisterControl(wxControl* const control, const wxString& description);
@@ -157,9 +190,6 @@ protected:
SettingCheckBox* borderless_fullscreen;
RefBoolSetting<wxCheckBox>* render_to_main_checkbox;
- SettingRadioButton* virtual_xfb;
- SettingRadioButton* real_xfb;
-
SettingCheckBox* cache_hires_textures;
wxCheckBox* progressive_scan_checkbox;
diff --git a/Source/Core/VideoBackends/Vulkan/VertexManager.cpp b/Source/Core/VideoBackends/Vulkan/VertexManager.cpp
index 1e97cf6308..ea9b27351b 100644
--- a/Source/Core/VideoBackends/Vulkan/VertexManager.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VertexManager.cpp
@@ -166,16 +166,19 @@ void VertexManager::vFlush()
}
// Bind all pending state to the command buffer
- g_renderer->SetPipeline(m_current_pipeline_object);
- if (!StateTracker::GetInstance()->Bind())
+ if (m_current_pipeline_object)
{
- WARN_LOG(VIDEO, "Skipped draw of %u indices", index_count);
- return;
- }
+ g_renderer->SetPipeline(m_current_pipeline_object);
+ if (!StateTracker::GetInstance()->Bind())
+ {
+ WARN_LOG(VIDEO, "Skipped draw of %u indices", index_count);
+ return;
+ }
- // Execute the draw
- vkCmdDrawIndexed(g_command_buffer_mgr->GetCurrentCommandBuffer(), index_count, 1,
- m_current_draw_base_index, m_current_draw_base_vertex, 0);
+ // Execute the draw
+ vkCmdDrawIndexed(g_command_buffer_mgr->GetCurrentCommandBuffer(), index_count, 1,
+ m_current_draw_base_index, m_current_draw_base_vertex, 0);
+ }
StateTracker::GetInstance()->OnDraw();
}
diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp
index b54b8060b9..8364b039c5 100644
--- a/Source/Core/VideoCommon/VertexManagerBase.cpp
+++ b/Source/Core/VideoCommon/VertexManagerBase.cpp
@@ -566,13 +566,25 @@ void VertexManagerBase::UpdatePipelineObject()
m_current_pipeline_object = nullptr;
m_pipeline_config_changed = false;
- if (g_ActiveConfig.iUberShaderMode == UberShaderMode::Disabled)
+ switch (g_ActiveConfig.iShaderCompilationMode)
+ {
+ case ShaderCompilationMode::Synchronous:
{
// Ubershaders disabled? Block and compile the specialized shader.
m_current_pipeline_object = g_shader_cache->GetPipelineForUid(m_current_pipeline_config);
- return;
}
- else if (g_ActiveConfig.iUberShaderMode == UberShaderMode::Hybrid)
+ break;
+
+ case ShaderCompilationMode::SynchronousUberShaders:
+ {
+ // Exclusive ubershader mode, always use ubershaders.
+ m_current_pipeline_object =
+ g_shader_cache->GetUberPipelineForUid(m_current_uber_pipeline_config);
+ }
+ break;
+
+ case ShaderCompilationMode::AsynchronousUberShaders:
+ case ShaderCompilationMode::AsynchronousSkipRendering:
{
// Can we background compile shaders? If so, get the pipeline asynchronously.
auto res = g_shader_cache->GetPipelineForUidAsync(m_current_pipeline_config);
@@ -582,8 +594,20 @@ void VertexManagerBase::UpdatePipelineObject()
m_current_pipeline_object = *res;
return;
}
- }
- // Exclusive ubershader mode, or hybrid and shaders are still compiling.
- m_current_pipeline_object = g_shader_cache->GetUberPipelineForUid(m_current_uber_pipeline_config);
+ if (g_ActiveConfig.iShaderCompilationMode == ShaderCompilationMode::AsynchronousUberShaders)
+ {
+ // Specialized shaders not ready, use the ubershaders.
+ m_current_pipeline_object =
+ g_shader_cache->GetUberPipelineForUid(m_current_uber_pipeline_config);
+ }
+ else
+ {
+ // Ensure we try again next draw. Otherwise, if no registers change between frames, the
+ // object will never be drawn, even when the shader is ready.
+ m_pipeline_config_changed = true;
+ }
+ }
+ break;
+ }
}
diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp
index 55abd69e75..9c90c009a0 100644
--- a/Source/Core/VideoCommon/VideoConfig.cpp
+++ b/Source/Core/VideoCommon/VideoConfig.cpp
@@ -103,7 +103,8 @@ void VideoConfig::Refresh()
iCommandBufferExecuteInterval = Config::Get(Config::GFX_COMMAND_BUFFER_EXECUTE_INTERVAL);
bShaderCache = Config::Get(Config::GFX_SHADER_CACHE);
bWaitForShadersBeforeStarting = Config::Get(Config::GFX_WAIT_FOR_SHADERS_BEFORE_STARTING);
- iUberShaderMode = static_cast<UberShaderMode>(Config::Get(Config::GFX_UBERSHADER_MODE));
+ iShaderCompilationMode =
+ static_cast<ShaderCompilationMode>(Config::Get(Config::GFX_SHADER_COMPILATION_MODE));
iShaderCompilerThreads = Config::Get(Config::GFX_SHADER_COMPILER_THREADS);
iShaderPrecompilerThreads = Config::Get(Config::GFX_SHADER_PRECOMPILER_THREADS);
@@ -178,6 +179,12 @@ bool VideoConfig::IsVSync() const
return bVSync && !Core::GetIsThrottlerTempDisabled();
}
+bool VideoConfig::UsingUberShaders() const
+{
+ return iShaderCompilationMode == ShaderCompilationMode::SynchronousUberShaders ||
+ iShaderCompilationMode == ShaderCompilationMode::AsynchronousUberShaders;
+}
+
static u32 GetNumAutoShaderCompilerThreads()
{
// Automatic number. We use clamp(cpus - 3, 1, 4).
diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h
index c8bded371b..8e22765695 100644
--- a/Source/Core/VideoCommon/VideoConfig.h
+++ b/Source/Core/VideoCommon/VideoConfig.h
@@ -42,11 +42,12 @@ enum class StereoMode : int
Nvidia3DVision
};
-enum class UberShaderMode : int
+enum class ShaderCompilationMode : int
{
- Disabled,
- Hybrid,
- Exclusive
+ Synchronous,
+ SynchronousUberShaders,
+ AsynchronousUberShaders,
+ AsynchronousSkipRendering
};
struct ProjectionHackConfig final
@@ -170,7 +171,7 @@ struct VideoConfig final
// Shader compilation settings.
bool bWaitForShadersBeforeStarting;
- UberShaderMode iUberShaderMode;
+ ShaderCompilationMode iShaderCompilationMode;
// Number of shader compiler threads.
// 0 disables background compilation.
@@ -238,7 +239,7 @@ struct VideoConfig final
return backend_info.bSupportsGPUTextureDecoding && bEnableGPUTextureDecoding;
}
bool UseVertexRounding() const { return bVertexRounding && iEFBScale != 1; }
- bool UsingUberShaders() const { return iUberShaderMode != UberShaderMode::Disabled; }
+ bool UsingUberShaders() const;
u32 GetShaderCompilerThreads() const;
u32 GetShaderPrecompilerThreads() const;
};