diff options
Diffstat (limited to 'src/video_core/gpu_logging')
| -rw-r--r-- | src/video_core/gpu_logging/gpu_logging.cpp | 62 | ||||
| -rw-r--r-- | src/video_core/gpu_logging/gpu_logging.h | 12 |
2 files changed, 33 insertions, 41 deletions
diff --git a/src/video_core/gpu_logging/gpu_logging.cpp b/src/video_core/gpu_logging/gpu_logging.cpp index 5f5e376e99..72e48e4996 100644 --- a/src/video_core/gpu_logging/gpu_logging.cpp +++ b/src/video_core/gpu_logging/gpu_logging.cpp @@ -4,6 +4,7 @@ #include "video_core/gpu_logging/gpu_logging.h" #include <fmt/format.h> +#include <mutex> #include <thread> #include "common/fs/file.h" @@ -280,13 +281,12 @@ void GPULogger::LogMemoryDeallocation(uintptr_t memory) { } void GPULogger::LogShaderCompilation(const std::string& shader_name, - const std::string& shader_info, - std::span<const u32> spirv_code) { + const std::string& shader_info) { if (!initialized || current_level == LogLevel::Off) { return; } - if (!dump_shaders && current_level < LogLevel::Verbose) { + if (current_level < LogLevel::Verbose) { return; } @@ -294,38 +294,36 @@ void GPULogger::LogShaderCompilation(const std::string& shader_name, std::chrono::steady_clock::now().time_since_epoch()); const auto log_entry = fmt::format("[{}] [Shader] Compiled: {} ({})\n", - FormatTimestamp(timestamp), shader_name, shader_info); + FormatTimestamp(timestamp), shader_name, shader_info); WriteToLog(log_entry); +} - // Dump SPIR-V binary if enabled and we have data - if (dump_shaders && !spirv_code.empty()) { - using namespace Common::FS; - const auto& log_dir = GetEdenPath(EdenPath::LogDir); - const auto shaders_dir = log_dir / "shaders"; +bool IsActive() noexcept { + return Settings::values.gpu_log_level.GetValue() != Settings::GpuLogLevel::Off; +} - // Create directory on first dump - if (!shader_dump_dir_created) { - [[maybe_unused]] const bool created = CreateDir(shaders_dir); - shader_dump_dir_created = true; - } +void DumpSpirvShader(u64 shader_hash, std::span<const u32> spirv_code) { + if (spirv_code.empty()) { + return; + } - // Write SPIR-V binary file - const auto shader_path = shaders_dir / fmt::format("{}.spv", shader_name); - auto shader_file = std::make_unique<Common::FS::IOFile>( - shader_path, FileAccessMode::Write, FileType::BinaryFile); - - if (shader_file->IsOpen()) { - const size_t bytes_to_write = spirv_code.size() * sizeof(u32); - static_cast<void>(shader_file->WriteSpan(spirv_code)); - shader_file->Close(); - - const auto dump_log = fmt::format("[{}] [Shader] Dumped SPIR-V: {} ({} bytes)\n", - FormatTimestamp(timestamp), shader_path.string(), bytes_to_write); - WriteToLog(dump_log); - } else { - LOG_WARNING(Render_Vulkan, "[GPU Logging] Failed to dump shader: {}", shader_path.string()); - } + using namespace Common::FS; + const auto& dump_dir = GetEdenPath(EdenPath::DumpDir); + + // Ensure DumpDir exists once. CreateDir is idempotent, so guarded to skip the syscall. + static std::once_flag dump_dir_flag; + std::call_once(dump_dir_flag, [&dump_dir]() { + [[maybe_unused]] const bool created = CreateDir(dump_dir); + }); + + const auto shader_path = dump_dir / fmt::format("{:016x}_{:016x}.spv", + Settings::GetCurrentProgramID(), shader_hash); + Common::FS::IOFile shader_file(shader_path, FileAccessMode::Write, FileType::BinaryFile); + if (!shader_file.IsOpen()) { + LOG_WARNING(Render_Vulkan, "[Shader Dump] Failed to open {}", shader_path.string()); + return; } + static_cast<void>(shader_file.WriteSpan(spirv_code)); } void GPULogger::LogPipelineStateChange(const std::string& state_info) { @@ -657,10 +655,6 @@ void GPULogger::EnableVulkanCallTracking(bool enabled) { track_vulkan_calls = enabled; } -void GPULogger::EnableShaderDumps(bool enabled) { - dump_shaders = enabled; -} - void GPULogger::EnableMemoryTracking(bool enabled) { track_memory = enabled; } diff --git a/src/video_core/gpu_logging/gpu_logging.h b/src/video_core/gpu_logging/gpu_logging.h index 134fa94c0f..b16988ed0b 100644 --- a/src/video_core/gpu_logging/gpu_logging.h +++ b/src/video_core/gpu_logging/gpu_logging.h @@ -87,8 +87,7 @@ public: void LogVulkanCall(const std::string& call_name, const std::string& params, int result); void LogMemoryAllocation(uintptr_t memory, u64 size, u32 memory_flags); void LogMemoryDeallocation(uintptr_t memory); - void LogShaderCompilation(const std::string& shader_name, const std::string& shader_info, - std::span<const u32> spirv_code = {}); + void LogShaderCompilation(const std::string& shader_name, const std::string& shader_info); void LogPipelineStateChange(const std::string& state_info); void LogDriverDebugInfo(const std::string& debug_info); @@ -121,7 +120,6 @@ public: // Settings void SetLogLevel(LogLevel level); void EnableVulkanCallTracking(bool enabled); - void EnableShaderDumps(bool enabled); void EnableMemoryTracking(bool enabled); void EnableDriverDebugInfo(bool enabled); void SetRingBufferSize(size_t entries); @@ -171,7 +169,6 @@ private: // Feature flags bool track_vulkan_calls = true; - bool dump_shaders = false; bool track_memory = false; bool capture_driver_debug = false; @@ -179,15 +176,16 @@ private: std::set<std::string> used_extensions; mutable std::mutex extension_mutex; - // Shader dump directory (created on demand) - bool shader_dump_dir_created = false; - // Stored state for crash dumps std::string stored_driver_debug_info; std::string stored_pipeline_state; mutable std::mutex state_mutex; }; +[[nodiscard]] bool IsActive() noexcept; + +void DumpSpirvShader(u64 shader_hash, std::span<const u32> spirv_code); + // Helper to get stage name from index inline const char* GetShaderStageName(size_t stage_index) { static constexpr std::array<const char*, 5> stage_names{ |
