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.
This commit is contained in:
parent
4cd8b2f1f7
commit
51512d01d8
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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(),
|
return std::ranges::find(gl_cache, id, &ShaderDiskCachePrecompiled::unique_identifier);
|
||||||
[id](const auto& entry) { return entry.unique_identifier == id; });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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()) {
|
if (device.UseAssemblyShaders() || device.UseDriverCache()) {
|
||||||
// Don't store precompiled binaries for assembly shaders.
|
// Don't store precompiled binaries for assembly shaders or when using the driver cache
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Reference in New Issue