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:
xbzk 2026-06-27 02:52:13 +02:00 committed by crueter
parent 629ebf1bde
commit 09b6b3b71e
No known key found for this signature in database
GPG key ID: 425ACD2D4830EBC6
29 changed files with 335 additions and 194 deletions

View file

@ -87,7 +87,7 @@ ComputePipeline::ComputePipeline(const Device& device_, Scheduler& scheduler, vk
}, *pipeline_cache);
// Log compute pipeline creation
if (Settings::values.gpu_logging_enabled.GetValue()) {
if (GPU::Logging::IsActive()) {
GPU::Logging::GPULogger::GetInstance().LogPipelineStateChange(
"ComputePipeline created"
);
@ -223,7 +223,7 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
}
// Log compute pipeline binding
if (Settings::values.gpu_logging_enabled.GetValue() &&
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
GPU::Logging::GPULogger::GetInstance().LogPipelineBind(true, "compute pipeline");
}

View file

@ -532,7 +532,7 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
const bool bind_pipeline{scheduler.UpdateGraphicsPipeline(this)};
// Log graphics pipeline binding
if (bind_pipeline && Settings::values.gpu_logging_enabled.GetValue() &&
if (bind_pipeline && GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
const std::string pipeline_info = fmt::format("hash=0x{:016x}", key.Hash());
GPU::Logging::GPULogger::GetInstance().LogPipelineBind(false, pipeline_info);
@ -986,7 +986,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
}, *pipeline_cache);
// Log graphics pipeline creation
if (Settings::values.gpu_logging_enabled.GetValue()) {
if (GPU::Logging::IsActive()) {
const std::string pipeline_info = fmt::format(
"GraphicsPipeline created: stages={}, attachments={}",
shader_stages.size(),

View file

@ -751,7 +751,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
programs[index] = MergeDualVertexPrograms(program_va, program_vb, env);
}
if (Settings::values.dump_shaders) {
if (Settings::values.dump_guest_shaders) {
env.Dump(hash, key.unique_hashes[index]);
}
@ -783,14 +783,22 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
device.SaveShader(code);
modules[stage_index] = BuildShader(device, code);
// Log shader compilation to GPU logger (with SPIR-V binary dump if enabled)
if (Settings::values.gpu_logging_enabled.GetValue()) {
// Text log + .spv dump. Text log is gated by gpu_log_level != Off; .spv dump
// is independent and gated only by gpu_log_shader_dumps.
const bool should_log = GPU::Logging::IsActive();
const bool should_dump = Settings::values.gpu_log_shader_dumps.GetValue();
if (should_log || should_dump) {
static constexpr std::array stage_names{"vertex", "tess_control", "tess_eval", "geometry", "fragment"};
const std::string shader_name = fmt::format("shader_{:016x}_{}", key.unique_hashes[index], stage_names[stage_index]);
const std::string shader_info = fmt::format("SPIR-V size: {} bytes, hash: {:016x}",
code.size() * sizeof(u32), key.unique_hashes[index]);
GPU::Logging::GPULogger::GetInstance().LogShaderCompilation(shader_name, shader_info,
std::span<const u32>(code.data(), code.size()));
if (should_log) {
const std::string shader_info = fmt::format("SPIR-V size: {} bytes, hash: {:016x}",
code.size() * sizeof(u32), key.unique_hashes[index]);
GPU::Logging::GPULogger::GetInstance().LogShaderCompilation(shader_name, shader_info);
}
if (should_dump) {
GPU::Logging::DumpSpirvShader(key.unique_hashes[index],
std::span<const u32>(code.data(), code.size()));
}
}
if (device.HasDebuggingToolAttached()) {
@ -879,7 +887,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
// Dump it before error.
if (Settings::values.dump_shaders) {
if (Settings::values.dump_guest_shaders) {
env.Dump(hash, key.unique_hash);
}
@ -901,13 +909,20 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
device.SaveShader(code);
vk::ShaderModule spv_module{BuildShader(device, code)};
// Log compute shader compilation to GPU logger (with SPIR-V binary dump if enabled)
if (Settings::values.gpu_logging_enabled.GetValue()) {
// Text log + .spv dump. Same split as the graphics path.
const bool should_log = GPU::Logging::IsActive();
const bool should_dump = Settings::values.gpu_log_shader_dumps.GetValue();
if (should_log || should_dump) {
const std::string shader_name = fmt::format("shader_{:016x}_compute", key.unique_hash);
const std::string shader_info = fmt::format("SPIR-V size: {} bytes, hash: {:016x}",
code.size() * sizeof(u32), key.unique_hash);
GPU::Logging::GPULogger::GetInstance().LogShaderCompilation(shader_name, shader_info,
std::span<const u32>(code.data(), code.size()));
if (should_log) {
const std::string shader_info = fmt::format("SPIR-V size: {} bytes, hash: {:016x}",
code.size() * sizeof(u32), key.unique_hash);
GPU::Logging::GPULogger::GetInstance().LogShaderCompilation(shader_name, shader_info);
}
if (should_dump) {
GPU::Logging::DumpSpirvShader(key.unique_hash,
std::span<const u32>(code.data(), code.size()));
}
}
if (device.HasDebuggingToolAttached()) {

View file

@ -270,7 +270,7 @@ void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
});
// Log draw call
if (Settings::values.gpu_logging_enabled.GetValue() &&
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
const std::string params = is_indexed ?
fmt::format("vertices={}, instances={}, firstIndex={}, baseVertex={}, baseInstance={}",
@ -331,7 +331,7 @@ void RasterizerVulkan::DrawIndirect() {
});
// Log indirect draw call
if (Settings::values.gpu_logging_enabled.GetValue() &&
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
const std::string log_params = fmt::format("drawCount={}, stride={}",
params.max_draw_counts, params.stride);
@ -585,7 +585,7 @@ void RasterizerVulkan::DispatchCompute() {
scheduler.Record([dim](vk::CommandBuffer cmdbuf) { cmdbuf.Dispatch(dim[0], dim[1], dim[2]); });
// Log compute dispatch
if (Settings::values.gpu_logging_enabled.GetValue() &&
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
const std::string params = fmt::format("groupCountX={}, groupCountY={}, groupCountZ={}",
dim[0], dim[1], dim[2]);
@ -1110,7 +1110,7 @@ void RasterizerVulkan::HandleTransformFeedback() {
regs.transform_feedback_enabled);
if (regs.transform_feedback_enabled != 0) {
// Log extension usage for transform feedback
if (Settings::values.gpu_logging_enabled.GetValue()) {
if (GPU::Logging::IsActive()) {
GPU::Logging::GPULogger::GetInstance().LogExtensionUsage(
"VK_EXT_transform_feedback", "HandleTransformFeedback");
}

View file

@ -181,7 +181,7 @@ void Scheduler::RequestRenderpass(const Framebuffer* framebuffer) {
state.render_area = render_area;
// Log render pass begin
if (Settings::values.gpu_logging_enabled.GetValue() &&
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
const std::string render_pass_info = fmt::format(
"renderArea={}x{}, numImages={}",
@ -292,7 +292,7 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se
cmdbuf, upload_cmdbuf, signal_semaphore, wait_semaphore, signal_value)) {
case VK_SUCCESS:
// Log successful queue submission
if (Settings::values.gpu_logging_enabled.GetValue() &&
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
GPU::Logging::GPULogger::GetInstance().LogVulkanCall(
"vkQueueSubmit", "", VK_SUCCESS);
@ -335,7 +335,7 @@ void Scheduler::EndRenderPass()
query_cache->CounterClose(VideoCommon::QueryType::StreamingByteCount);
// Log render pass end
if (Settings::values.gpu_logging_enabled.GetValue() &&
if (GPU::Logging::IsActive() &&
Settings::values.gpu_log_vulkan_calls.GetValue()) {
GPU::Logging::GPULogger::GetInstance().LogRenderPassEnd();
}

View file

@ -2332,7 +2332,7 @@ Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& t
if (has_custom_border_colors) {
pnext = &border_ci;
// Log extension usage for custom border color
if (Settings::values.gpu_logging_enabled.GetValue()) {
if (GPU::Logging::IsActive()) {
GPU::Logging::GPULogger::GetInstance().LogExtensionUsage(
"VK_EXT_custom_border_color", "Sampler::Sampler");
}