diff options
| author | 2021-01-20 20:09:57 -0300 | |
|---|---|---|
| committer | 2021-01-21 00:41:03 -0300 | |
| commit | 51512d01d8e956b2afada91e51dfd7c0a6444ad6 (patch) | |
| tree | 920ed6ec21b438894b7caeef0a946dbfc2ead10a /src | |
| parent | Merge pull request #5755 from FearlessTobi/port-5344 (diff) | |
| download | yuzu-51512d01d8e956b2afada91e51dfd7c0a6444ad6.tar.gz yuzu-51512d01d8e956b2afada91e51dfd7c0a6444ad6.tar.xz yuzu-51512d01d8e956b2afada91e51dfd7c0a6444ad6.zip | |
renderer_opengl: Avoid precompiled cache and force NV GL cache directory
Setting __GL_SHADER_DISK_CACHE_PATH we can force the cache directory to
be in yuzu's user directory to stop commonly distributed malware from
deleting our driver shader cache. And by setting
__GL_SHADER_DISK_CACHE_SKIP_CLEANUP we can have an unbounded shader
cache size.
This has only been implemented on Windows, mostly because previous tests
didn't seem to work on Linux.
Disable the precompiled cache on Nvidia's driver. There's no need to
hide information the driver already has in its own cache.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/common/nvidia_flags.cpp | 27 | ||||
| -rw-r--r-- | src/common/nvidia_flags.h | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 13 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 3 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 3 |
8 files changed, 59 insertions, 5 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index f77575a00..bfd11e76d 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt | |||
| @@ -138,6 +138,8 @@ add_library(common STATIC | |||
| 138 | microprofile.h | 138 | microprofile.h |
| 139 | microprofileui.h | 139 | microprofileui.h |
| 140 | misc.cpp | 140 | misc.cpp |
| 141 | nvidia_flags.cpp | ||
| 142 | nvidia_flags.h | ||
| 141 | page_table.cpp | 143 | page_table.cpp |
| 142 | page_table.h | 144 | page_table.h |
| 143 | param_package.cpp | 145 | param_package.cpp |
diff --git a/src/common/nvidia_flags.cpp b/src/common/nvidia_flags.cpp new file mode 100644 index 000000000..d537517db --- /dev/null +++ b/src/common/nvidia_flags.cpp | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <filesystem> | ||
| 6 | #include <stdlib.h> | ||
| 7 | |||
| 8 | #include <fmt/format.h> | ||
| 9 | |||
| 10 | #include "common/file_util.h" | ||
| 11 | #include "common/nvidia_flags.h" | ||
| 12 | |||
| 13 | namespace Common { | ||
| 14 | |||
| 15 | void ConfigureNvidiaEnvironmentFlags() { | ||
| 16 | #ifdef _WIN32 | ||
| 17 | const std::string shader_path = Common::FS::SanitizePath( | ||
| 18 | fmt::format("{}/nvidia/", Common::FS::GetUserPath(Common::FS::UserPath::ShaderDir))); | ||
| 19 | const std::string windows_path = | ||
| 20 | Common::FS::SanitizePath(shader_path, Common::FS::DirectorySeparator::BackwardSlash); | ||
| 21 | void(Common::FS::CreateFullPath(shader_path + '/')); | ||
| 22 | void(_putenv(fmt::format("__GL_SHADER_DISK_CACHE_PATH={}", windows_path).c_str())); | ||
| 23 | void(_putenv("__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1")); | ||
| 24 | #endif | ||
| 25 | } | ||
| 26 | |||
| 27 | } // namespace Common | ||
diff --git a/src/common/nvidia_flags.h b/src/common/nvidia_flags.h new file mode 100644 index 000000000..75a0233ac --- /dev/null +++ b/src/common/nvidia_flags.h | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | namespace Common { | ||
| 6 | |||
| 7 | /// Configure platform specific flags for Nvidia's driver | ||
| 8 | void ConfigureNvidiaEnvironmentFlags(); | ||
| 9 | |||
| 10 | } // namespace Common | ||
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 81b71edfb..04c267ee4 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -246,6 +246,7 @@ Device::Device() | |||
| 246 | GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2; | 246 | GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2; |
| 247 | 247 | ||
| 248 | use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue(); | 248 | use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue(); |
| 249 | use_driver_cache = is_nvidia; | ||
| 249 | 250 | ||
| 250 | LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); | 251 | LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); |
| 251 | LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); | 252 | LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); |
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h index 3e79d1e37..9141de635 100644 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h | |||
| @@ -120,6 +120,10 @@ public: | |||
| 120 | return use_asynchronous_shaders; | 120 | return use_asynchronous_shaders; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | bool UseDriverCache() const { | ||
| 124 | return use_driver_cache; | ||
| 125 | } | ||
| 126 | |||
| 123 | private: | 127 | private: |
| 124 | static bool TestVariableAoffi(); | 128 | static bool TestVariableAoffi(); |
| 125 | static bool TestPreciseBug(); | 129 | static bool TestPreciseBug(); |
| @@ -147,6 +151,7 @@ private: | |||
| 147 | bool has_debugging_tool_attached{}; | 151 | bool has_debugging_tool_attached{}; |
| 148 | bool use_assembly_shaders{}; | 152 | bool use_assembly_shaders{}; |
| 149 | bool use_asynchronous_shaders{}; | 153 | bool use_asynchronous_shaders{}; |
| 154 | bool use_driver_cache{}; | ||
| 150 | }; | 155 | }; |
| 151 | 156 | ||
| 152 | } // namespace OpenGL | 157 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index d4841fdb7..529570ff0 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -159,6 +159,10 @@ std::unordered_set<GLenum> GetSupportedFormats() { | |||
| 159 | 159 | ||
| 160 | ProgramSharedPtr BuildShader(const Device& device, ShaderType shader_type, u64 unique_identifier, | 160 | ProgramSharedPtr BuildShader(const Device& device, ShaderType shader_type, u64 unique_identifier, |
| 161 | const ShaderIR& ir, const Registry& registry, bool hint_retrievable) { | 161 | const ShaderIR& ir, const Registry& registry, bool hint_retrievable) { |
| 162 | if (device.UseDriverCache()) { | ||
| 163 | // Ignore hint retrievable if we are using the driver cache | ||
| 164 | hint_retrievable = false; | ||
| 165 | } | ||
| 162 | const std::string shader_id = MakeShaderID(unique_identifier, shader_type); | 166 | const std::string shader_id = MakeShaderID(unique_identifier, shader_type); |
| 163 | LOG_INFO(Render_OpenGL, "{}", shader_id); | 167 | LOG_INFO(Render_OpenGL, "{}", shader_id); |
| 164 | 168 | ||
| @@ -336,7 +340,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop | |||
| 336 | } | 340 | } |
| 337 | 341 | ||
| 338 | std::vector<ShaderDiskCachePrecompiled> gl_cache; | 342 | std::vector<ShaderDiskCachePrecompiled> gl_cache; |
| 339 | if (!device.UseAssemblyShaders()) { | 343 | if (!device.UseAssemblyShaders() && !device.UseDriverCache()) { |
| 340 | // Only load precompiled cache when we are not using assembly shaders | 344 | // Only load precompiled cache when we are not using assembly shaders |
| 341 | gl_cache = disk_cache.LoadPrecompiled(); | 345 | gl_cache = disk_cache.LoadPrecompiled(); |
| 342 | } | 346 | } |
| @@ -356,8 +360,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop | |||
| 356 | std::atomic_bool gl_cache_failed = false; | 360 | std::atomic_bool gl_cache_failed = false; |
| 357 | 361 | ||
| 358 | const auto find_precompiled = [&gl_cache](u64 id) { | 362 | const auto find_precompiled = [&gl_cache](u64 id) { |
| 359 | return std::find_if(gl_cache.begin(), gl_cache.end(), | 363 | return std::ranges::find(gl_cache, id, &ShaderDiskCachePrecompiled::unique_identifier); |
| 360 | [id](const auto& entry) { return entry.unique_identifier == id; }); | ||
| 361 | }; | 364 | }; |
| 362 | 365 | ||
| 363 | const auto worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin, | 366 | const auto worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin, |
| @@ -432,8 +435,8 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop | |||
| 432 | return; | 435 | return; |
| 433 | } | 436 | } |
| 434 | 437 | ||
| 435 | if (device.UseAssemblyShaders()) { | 438 | if (device.UseAssemblyShaders() || device.UseDriverCache()) { |
| 436 | // Don't store precompiled binaries for assembly shaders. | 439 | // Don't store precompiled binaries for assembly shaders or when using the driver cache |
| 437 | return; | 440 | return; |
| 438 | } | 441 | } |
| 439 | 442 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 2e74037d1..e76141125 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include "applets/profile_select.h" | 16 | #include "applets/profile_select.h" |
| 17 | #include "applets/software_keyboard.h" | 17 | #include "applets/software_keyboard.h" |
| 18 | #include "applets/web_browser.h" | 18 | #include "applets/web_browser.h" |
| 19 | #include "common/nvidia_flags.h" | ||
| 19 | #include "configuration/configure_input.h" | 20 | #include "configuration/configure_input.h" |
| 20 | #include "configuration/configure_per_game.h" | 21 | #include "configuration/configure_per_game.h" |
| 21 | #include "configuration/configure_vibration.h" | 22 | #include "configuration/configure_vibration.h" |
| @@ -3023,6 +3024,8 @@ int main(int argc, char* argv[]) { | |||
| 3023 | MicroProfileOnThreadCreate("Frontend"); | 3024 | MicroProfileOnThreadCreate("Frontend"); |
| 3024 | SCOPE_EXIT({ MicroProfileShutdown(); }); | 3025 | SCOPE_EXIT({ MicroProfileShutdown(); }); |
| 3025 | 3026 | ||
| 3027 | Common::ConfigureNvidiaEnvironmentFlags(); | ||
| 3028 | |||
| 3026 | // Init settings params | 3029 | // Init settings params |
| 3027 | QCoreApplication::setOrganizationName(QStringLiteral("yuzu team")); | 3030 | QCoreApplication::setOrganizationName(QStringLiteral("yuzu team")); |
| 3028 | QCoreApplication::setApplicationName(QStringLiteral("yuzu")); | 3031 | QCoreApplication::setApplicationName(QStringLiteral("yuzu")); |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 4faf62ede..0e1f3bdb3 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include "common/logging/filter.h" | 17 | #include "common/logging/filter.h" |
| 18 | #include "common/logging/log.h" | 18 | #include "common/logging/log.h" |
| 19 | #include "common/microprofile.h" | 19 | #include "common/microprofile.h" |
| 20 | #include "common/nvidia_flags.h" | ||
| 20 | #include "common/scm_rev.h" | 21 | #include "common/scm_rev.h" |
| 21 | #include "common/scope_exit.h" | 22 | #include "common/scope_exit.h" |
| 22 | #include "common/string_util.h" | 23 | #include "common/string_util.h" |
| @@ -152,6 +153,8 @@ int main(int argc, char** argv) { | |||
| 152 | MicroProfileOnThreadCreate("EmuThread"); | 153 | MicroProfileOnThreadCreate("EmuThread"); |
| 153 | SCOPE_EXIT({ MicroProfileShutdown(); }); | 154 | SCOPE_EXIT({ MicroProfileShutdown(); }); |
| 154 | 155 | ||
| 156 | Common::ConfigureNvidiaEnvironmentFlags(); | ||
| 157 | |||
| 155 | if (filepath.empty()) { | 158 | if (filepath.empty()) { |
| 156 | LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); | 159 | LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); |
| 157 | return -1; | 160 | return -1; |