Jelajahi Sumber

Merge pull request #5778 from ReinUsesLisp/shader-dir

renderer_opengl: Avoid precompiled cache and force NV GL cache directory
bunnei 5 tahun lalu
induk
melakukan
28b822fe38

+ 2 - 0
src/common/CMakeLists.txt

@@ -138,6 +138,8 @@ add_library(common STATIC
     microprofile.h
     microprofile.h
     microprofileui.h
     microprofileui.h
     misc.cpp
     misc.cpp
+    nvidia_flags.cpp
+    nvidia_flags.h
     page_table.cpp
     page_table.cpp
     page_table.h
     page_table.h
     param_package.cpp
     param_package.cpp

+ 27 - 0
src/common/nvidia_flags.cpp

@@ -0,0 +1,27 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <filesystem>
+#include <stdlib.h>
+
+#include <fmt/format.h>
+
+#include "common/file_util.h"
+#include "common/nvidia_flags.h"
+
+namespace Common {
+
+void ConfigureNvidiaEnvironmentFlags() {
+#ifdef _WIN32
+    const std::string shader_path = Common::FS::SanitizePath(
+        fmt::format("{}/nvidia/", Common::FS::GetUserPath(Common::FS::UserPath::ShaderDir)));
+    const std::string windows_path =
+        Common::FS::SanitizePath(shader_path, Common::FS::DirectorySeparator::BackwardSlash);
+    void(Common::FS::CreateFullPath(shader_path + '/'));
+    void(_putenv(fmt::format("__GL_SHADER_DISK_CACHE_PATH={}", windows_path).c_str()));
+    void(_putenv("__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1"));
+#endif
+}
+
+} // namespace Common

+ 10 - 0
src/common/nvidia_flags.h

@@ -0,0 +1,10 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+namespace Common {
+
+/// Configure platform specific flags for Nvidia's driver
+void ConfigureNvidiaEnvironmentFlags();
+
+} // namespace Common

+ 1 - 0
src/video_core/renderer_opengl/gl_device.cpp

@@ -246,6 +246,7 @@ Device::Device()
                            GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2;
                            GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2;
 
 
     use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue();
     use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue();
+    use_driver_cache = is_nvidia;
 
 
     LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi);
     LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi);
     LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug);
     LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug);

+ 5 - 0
src/video_core/renderer_opengl/gl_device.h

@@ -120,6 +120,10 @@ public:
         return use_asynchronous_shaders;
         return use_asynchronous_shaders;
     }
     }
 
 
+    bool UseDriverCache() const {
+        return use_driver_cache;
+    }
+
 private:
 private:
     static bool TestVariableAoffi();
     static bool TestVariableAoffi();
     static bool TestPreciseBug();
     static bool TestPreciseBug();
@@ -147,6 +151,7 @@ private:
     bool has_debugging_tool_attached{};
     bool has_debugging_tool_attached{};
     bool use_assembly_shaders{};
     bool use_assembly_shaders{};
     bool use_asynchronous_shaders{};
     bool use_asynchronous_shaders{};
+    bool use_driver_cache{};
 };
 };
 
 
 } // namespace OpenGL
 } // namespace OpenGL

+ 8 - 5
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -159,6 +159,10 @@ std::unordered_set<GLenum> GetSupportedFormats() {
 
 
 ProgramSharedPtr BuildShader(const Device& device, ShaderType shader_type, u64 unique_identifier,
 ProgramSharedPtr BuildShader(const Device& device, ShaderType shader_type, u64 unique_identifier,
                              const ShaderIR& ir, const Registry& registry, bool hint_retrievable) {
                              const ShaderIR& ir, const Registry& registry, bool hint_retrievable) {
+    if (device.UseDriverCache()) {
+        // Ignore hint retrievable if we are using the driver cache
+        hint_retrievable = false;
+    }
     const std::string shader_id = MakeShaderID(unique_identifier, shader_type);
     const std::string shader_id = MakeShaderID(unique_identifier, shader_type);
     LOG_INFO(Render_OpenGL, "{}", shader_id);
     LOG_INFO(Render_OpenGL, "{}", shader_id);
 
 
@@ -336,7 +340,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop
     }
     }
 
 
     std::vector<ShaderDiskCachePrecompiled> gl_cache;
     std::vector<ShaderDiskCachePrecompiled> gl_cache;
-    if (!device.UseAssemblyShaders()) {
+    if (!device.UseAssemblyShaders() && !device.UseDriverCache()) {
         // Only load precompiled cache when we are not using assembly shaders
         // Only load precompiled cache when we are not using assembly shaders
         gl_cache = disk_cache.LoadPrecompiled();
         gl_cache = disk_cache.LoadPrecompiled();
     }
     }
@@ -356,8 +360,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop
     std::atomic_bool gl_cache_failed = false;
     std::atomic_bool gl_cache_failed = false;
 
 
     const auto find_precompiled = [&gl_cache](u64 id) {
     const auto find_precompiled = [&gl_cache](u64 id) {
-        return std::find_if(gl_cache.begin(), gl_cache.end(),
-                            [id](const auto& entry) { return entry.unique_identifier == id; });
+        return std::ranges::find(gl_cache, id, &ShaderDiskCachePrecompiled::unique_identifier);
     };
     };
 
 
     const auto worker = [&](Core::Frontend::GraphicsContext* context, std::size_t begin,
     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
         return;
         return;
     }
     }
 
 
-    if (device.UseAssemblyShaders()) {
-        // Don't store precompiled binaries for assembly shaders.
+    if (device.UseAssemblyShaders() || device.UseDriverCache()) {
+        // Don't store precompiled binaries for assembly shaders or when using the driver cache
         return;
         return;
     }
     }
 
 

+ 3 - 0
src/yuzu/main.cpp

@@ -16,6 +16,7 @@
 #include "applets/profile_select.h"
 #include "applets/profile_select.h"
 #include "applets/software_keyboard.h"
 #include "applets/software_keyboard.h"
 #include "applets/web_browser.h"
 #include "applets/web_browser.h"
+#include "common/nvidia_flags.h"
 #include "configuration/configure_input.h"
 #include "configuration/configure_input.h"
 #include "configuration/configure_per_game.h"
 #include "configuration/configure_per_game.h"
 #include "configuration/configure_vibration.h"
 #include "configuration/configure_vibration.h"
@@ -3023,6 +3024,8 @@ int main(int argc, char* argv[]) {
     MicroProfileOnThreadCreate("Frontend");
     MicroProfileOnThreadCreate("Frontend");
     SCOPE_EXIT({ MicroProfileShutdown(); });
     SCOPE_EXIT({ MicroProfileShutdown(); });
 
 
+    Common::ConfigureNvidiaEnvironmentFlags();
+
     // Init settings params
     // Init settings params
     QCoreApplication::setOrganizationName(QStringLiteral("yuzu team"));
     QCoreApplication::setOrganizationName(QStringLiteral("yuzu team"));
     QCoreApplication::setApplicationName(QStringLiteral("yuzu"));
     QCoreApplication::setApplicationName(QStringLiteral("yuzu"));

+ 3 - 0
src/yuzu_cmd/yuzu.cpp

@@ -17,6 +17,7 @@
 #include "common/logging/filter.h"
 #include "common/logging/filter.h"
 #include "common/logging/log.h"
 #include "common/logging/log.h"
 #include "common/microprofile.h"
 #include "common/microprofile.h"
+#include "common/nvidia_flags.h"
 #include "common/scm_rev.h"
 #include "common/scm_rev.h"
 #include "common/scope_exit.h"
 #include "common/scope_exit.h"
 #include "common/string_util.h"
 #include "common/string_util.h"
@@ -152,6 +153,8 @@ int main(int argc, char** argv) {
     MicroProfileOnThreadCreate("EmuThread");
     MicroProfileOnThreadCreate("EmuThread");
     SCOPE_EXIT({ MicroProfileShutdown(); });
     SCOPE_EXIT({ MicroProfileShutdown(); });
 
 
+    Common::ConfigureNvidiaEnvironmentFlags();
+
     if (filepath.empty()) {
     if (filepath.empty()) {
         LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
         LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified");
         return -1;
         return -1;