From d92b7506c2ccd837dfba46f55a8521a463670b05 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Thu, 21 Jan 2021 01:01:05 +0100 Subject: [PATCH] early-access version 1345 --- README.md | 2 +- src/common/CMakeLists.txt | 2 ++ src/common/nvidia_flags.cpp | 25 ++++++++++++++ src/common/nvidia_flags.h | 10 ++++++ src/core/hle/service/lm/lm.cpp | 33 ++++++++++--------- src/video_core/renderer_opengl/gl_device.cpp | 1 + src/video_core/renderer_opengl/gl_device.h | 5 +++ .../renderer_opengl/gl_shader_cache.cpp | 13 +++++--- src/yuzu/main.cpp | 3 ++ src/yuzu_cmd/yuzu.cpp | 3 ++ 10 files changed, 76 insertions(+), 21 deletions(-) create mode 100755 src/common/nvidia_flags.cpp create mode 100755 src/common/nvidia_flags.h diff --git a/README.md b/README.md index 8b9a15bca..e7a73de8c 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1344. +This is the source code for early-access 1345. ## Legal Notice diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index f77575a00..bfd11e76d 100755 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -138,6 +138,8 @@ add_library(common STATIC microprofile.h microprofileui.h misc.cpp + nvidia_flags.cpp + nvidia_flags.h page_table.cpp page_table.h param_package.cpp diff --git a/src/common/nvidia_flags.cpp b/src/common/nvidia_flags.cpp new file mode 100755 index 000000000..c7f91ea85 --- /dev/null +++ b/src/common/nvidia_flags.cpp @@ -0,0 +1,25 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include + +#include + +#include "common/file_util.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)), + Common::FS::DirectorySeparator::PlatformDefault); + std::filesystem::create_directories(shader_path); + void(_putenv(fmt::format("__GL_SHADER_DISK_CACHE_PATH={}", shader_path).c_str())); + void(_putenv("__GL_SHADER_DISK_CACHE_SKIP_CLEANUP=1")); +#endif +} + +} // namespace Common diff --git a/src/common/nvidia_flags.h b/src/common/nvidia_flags.h new file mode 100755 index 000000000..75a0233ac --- /dev/null +++ b/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 diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index 5fcb753dc..4e0b4ea09 100755 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -26,20 +26,20 @@ enum class LogSeverity : u8 { }; // To keep flags out of hashing as well as the payload size -struct LogPacketHeaderEntrty { +struct LogPacketHeaderEntry { u64_le pid{}; u64_le tid{}; LogSeverity severity{}; u8 verbosity{}; - auto operator<=>(const LogPacketHeaderEntrty&) const = default; + auto operator<=>(const LogPacketHeaderEntry&) const = default; }; } // namespace Service::LM namespace std { template <> -struct hash { - std::size_t operator()(const Service::LM::LogPacketHeaderEntrty& k) const { +struct hash { + std::size_t operator()(const Service::LM::LogPacketHeaderEntry& k) const noexcept { std::size_t seed{}; boost::hash_combine(seed, k.pid); boost::hash_combine(seed, k.tid); @@ -95,7 +95,7 @@ private: std::memcpy(&header, data.data(), sizeof(LogPacketHeader)); offset += sizeof(LogPacketHeader); - LogPacketHeaderEntrty entry{ + LogPacketHeaderEntry entry{ .pid = header.pid, .tid = header.tid, .severity = header.severity, @@ -157,9 +157,12 @@ private: return result; } - std::string ReadString(const std::vector& data, std::size_t& offset, std::size_t length) { + std::optional ReadString(const std::vector& data, std::size_t& offset, + std::size_t length) { + if (length == 0) { + return std::nullopt; + } std::string output(length, '\0'); - output.resize(length); std::memcpy(output.data(), data.data() + offset, length); offset += length; return output; @@ -181,7 +184,7 @@ private: return output; } - void ParseLog(const LogPacketHeaderEntrty entry, const std::vector& log_data) { + void ParseLog(const LogPacketHeaderEntry entry, const std::vector& log_data) { // Possible entries std::optional text_log; std::optional line_number; @@ -233,16 +236,16 @@ private: } std::string output_log{}; - if (process_name && process_name->empty()) { + if (process_name) { output_log += fmt::format("Process: {}\n", *process_name); } - if (module_name && !module_name->empty()) { + if (module_name) { output_log += fmt::format("Module: {}\n", *module_name); } - if (file_name && !file_name->empty()) { + if (file_name) { output_log += fmt::format("File: {}\n", *file_name); } - if (function_name && !function_name->empty()) { + if (function_name) { output_log += fmt::format("Function: {}\n", *function_name); } if (line_number && *line_number != 0) { @@ -251,7 +254,7 @@ private: output_log += fmt::format("ProcessID: {}\n", entry.pid); output_log += fmt::format("ThreadID: {}\n", entry.tid); - if (text_log && !text_log->empty()) { + if (text_log) { output_log += fmt::format("Log Text: {}\n", *text_log); } @@ -283,7 +286,7 @@ private: } } - std::string DestinationToString(LogDestination destination) { + static std::string DestinationToString(LogDestination destination) { if (True(destination & LogDestination::All)) { return "TargetManager | Uart | UartSleep"; } @@ -328,7 +331,7 @@ private: }; static_assert(sizeof(LogPacketHeader) == 0x18, "LogPacketHeader is an invalid size"); - std::unordered_map> entries{}; + std::unordered_map> entries{}; LogDestination destination{LogDestination::All}; }; diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 703391ca5..b9e9f20d6 100755 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp @@ -249,6 +249,7 @@ Device::Device() { GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2; 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_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 9e620f603..ee053776d 100755 --- a/src/video_core/renderer_opengl/gl_device.h +++ b/src/video_core/renderer_opengl/gl_device.h @@ -118,6 +118,10 @@ public: return use_asynchronous_shaders; } + bool UseDriverCache() const { + return use_driver_cache; + } + private: static bool TestVariableAoffi(); static bool TestPreciseBug(); @@ -145,6 +149,7 @@ private: bool has_debugging_tool_attached{}; bool use_assembly_shaders{}; bool use_asynchronous_shaders{}; + bool use_driver_cache{}; }; } // 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 100755 --- 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 GetSupportedFormats() { ProgramSharedPtr BuildShader(const Device& device, ShaderType shader_type, u64 unique_identifier, 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); LOG_INFO(Render_OpenGL, "{}", shader_id); @@ -336,7 +340,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop } std::vector gl_cache; - if (!device.UseAssemblyShaders()) { + if (!device.UseAssemblyShaders() && !device.UseDriverCache()) { // Only load precompiled cache when we are not using assembly shaders 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; 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, @@ -432,8 +435,8 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop 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; } diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 2e74037d1..e76141125 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -16,6 +16,7 @@ #include "applets/profile_select.h" #include "applets/software_keyboard.h" #include "applets/web_browser.h" +#include "common/nvidia_flags.h" #include "configuration/configure_input.h" #include "configuration/configure_per_game.h" #include "configuration/configure_vibration.h" @@ -3023,6 +3024,8 @@ int main(int argc, char* argv[]) { MicroProfileOnThreadCreate("Frontend"); SCOPE_EXIT({ MicroProfileShutdown(); }); + Common::ConfigureNvidiaEnvironmentFlags(); + // Init settings params QCoreApplication::setOrganizationName(QStringLiteral("yuzu team")); QCoreApplication::setApplicationName(QStringLiteral("yuzu")); diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 3279f0fd8..982c41785 100755 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -17,6 +17,7 @@ #include "common/logging/filter.h" #include "common/logging/log.h" #include "common/microprofile.h" +#include "common/nvidia_flags.h" #include "common/scm_rev.h" #include "common/scope_exit.h" #include "common/string_util.h" @@ -152,6 +153,8 @@ int main(int argc, char** argv) { MicroProfileOnThreadCreate("EmuThread"); SCOPE_EXIT({ MicroProfileShutdown(); }); + Common::ConfigureNvidiaEnvironmentFlags(); + if (filepath.empty()) { LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); return -1;