mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-26 17:12:03 +00:00
xbzk/gpu-logging_qt-controls_android-fix (#4018)
5af7771f83-Bugfix: Made gpu_log_level global-only (was per-game switchable). Fixed Android non-determinism where a per-game profile silently overrode the global to Off and trapped GPULogger::Initialize() in a dead state, making shader dumps fail invisibly. Android per-game UI now hides the whole GPU logging block; Qt UI is untouched (global-only anyway). bf4aabe8ab-Refactor/Cleanup: Removed gpu_logging_enabled master toggle as redundant with gpu_log_level == Off. Introduced GPU::Logging::IsActive() helper, replaced 14 call sites across vk_*.cpp. Refactored LogShaderCompilation() to be text-only and extracted SPIR-V dumping into a standalone GPU::Logging::DumpSpirvShader() free function. No singleton dependency, gated only by gpu_log_shader_dumps. Now gpu_log_level and gpu_log_shader_dumps are fully orthogonal. Cleaned up Android (BooleanSetting, SettingsItem, presenter, 7 locale string files). 865a1c5027-Refactor: Renamed dump_shaders → dump_guest_shaders to disambiguate from gpu_log_shader_dumps. Updated Qt label to "Dump Guest (Maxwell) Shaders" and rewrote the tooltip to mention .ash, the DumpDir/shaders/ location, and nvdisasm. 7cab456fdf-Feature: Added Qt UI control for GPU log level in the Logging session. Added gpu_log_shader_dumps checkbox to the Graphics column right below dump_guest_shaders. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4018 Reviewed-by: MaranBr <maranbr@eden-emu.dev>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
void DumpSpirvShader(u64 shader_hash, std::span<const u32> spirv_code) {
|
||||
if (spirv_code.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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{
|
||||
|
||||
Reference in New Issue
Block a user