mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-06-27 09:56:26 +02: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:
parent
629ebf1bde
commit
09b6b3b71e
29 changed files with 335 additions and 194 deletions
|
|
@ -83,9 +83,10 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
|||
ENABLE_OVERLAY("enable_overlay"),
|
||||
|
||||
// GPU Logging
|
||||
GPU_LOGGING_ENABLED("gpu_logging_enabled"),
|
||||
GPU_LOG_VULKAN_CALLS("gpu_log_vulkan_calls"),
|
||||
GPU_LOG_SHADER_DUMPS("gpu_log_shader_dumps"),
|
||||
DUMP_GUEST_SHADERS("dump_guest_shaders"),
|
||||
DUMP_MACROS("dump_macros"),
|
||||
GPU_LOG_MEMORY_TRACKING("gpu_log_memory_tracking"),
|
||||
GPU_LOG_DRIVER_DEBUG("gpu_log_driver_debug"),
|
||||
|
||||
|
|
|
|||
|
|
@ -931,13 +931,6 @@ abstract class SettingsItem(
|
|||
)
|
||||
|
||||
// GPU Logging settings
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.GPU_LOGGING_ENABLED,
|
||||
titleId = R.string.gpu_logging_enabled,
|
||||
descriptionId = R.string.gpu_logging_enabled_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
ByteSetting.GPU_LOG_LEVEL,
|
||||
|
|
@ -954,6 +947,13 @@ abstract class SettingsItem(
|
|||
descriptionId = R.string.gpu_log_vulkan_calls_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.DUMP_GUEST_SHADERS,
|
||||
titleId = R.string.dump_guest_shaders,
|
||||
descriptionId = R.string.dump_guest_shaders_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.GPU_LOG_SHADER_DUMPS,
|
||||
|
|
@ -961,6 +961,13 @@ abstract class SettingsItem(
|
|||
descriptionId = R.string.gpu_log_shader_dumps_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.DUMP_MACROS,
|
||||
titleId = R.string.dump_macros,
|
||||
descriptionId = R.string.dump_macros_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.GPU_LOG_MEMORY_TRACKING,
|
||||
|
|
|
|||
|
|
@ -1288,16 +1288,19 @@ class SettingsFragmentPresenter(
|
|||
add(ShortSetting.DEBUG_KNOBS.key)
|
||||
add(StringSetting.PROGRAM_ARGS.key)
|
||||
|
||||
if (!NativeConfig.isPerGameConfigLoaded()) {
|
||||
add(HeaderSetting(R.string.gpu_logging_header))
|
||||
add(BooleanSetting.GPU_LOGGING_ENABLED.key)
|
||||
add(ByteSetting.GPU_LOG_LEVEL.key)
|
||||
add(BooleanSetting.GPU_LOG_VULKAN_CALLS.key)
|
||||
add(BooleanSetting.DUMP_GUEST_SHADERS.key)
|
||||
add(BooleanSetting.GPU_LOG_SHADER_DUMPS.key)
|
||||
add(BooleanSetting.DUMP_MACROS.key)
|
||||
add(BooleanSetting.GPU_LOG_MEMORY_TRACKING.key)
|
||||
add(BooleanSetting.GPU_LOG_DRIVER_DEBUG.key)
|
||||
add(IntSetting.GPU_LOG_RING_BUFFER_SIZE.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun addCustomPathsSettings(sl: ArrayList<SettingsItem>) {
|
||||
sl.apply {
|
||||
|
|
|
|||
|
|
@ -569,8 +569,6 @@
|
|||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">تسجيل وحدة معالجة الرسومات</string>
|
||||
<string name="gpu_logging_enabled">تمكين تسجيل وحدة معالجة الرسومات</string>
|
||||
<string name="gpu_logging_enabled_description">تسجيل عمليات وحدة معالجة الرسومات في ملف eden_gpu.log لتصحيح أخطاء برامج تشغيل Adreno</string>
|
||||
<string name="gpu_log_level">مستوى السجل</string>
|
||||
<string name="gpu_log_level_description">مستوى التفاصيل لسجلات وحدة معالجة الرسومات (كلما زاد المستوى، زادت التفاصيل وزادت التكاليف الإضافية)</string>
|
||||
<string name="gpu_log_vulkan_calls">تسجيل استدعاءات واجهة برمجة تطبيقات Vulkan</string>
|
||||
|
|
|
|||
|
|
@ -563,8 +563,6 @@
|
|||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">Registros de la GPU</string>
|
||||
<string name="gpu_logging_enabled">Activar los registros de la GPU</string>
|
||||
<string name="gpu_logging_enabled_description">Registra las operaciones de la GPU en eden_gpu.log para la depuración de los controladores de Adreno</string>
|
||||
<string name="gpu_log_level">Nivel de registros</string>
|
||||
<string name="gpu_log_level_description">Nivel de detalle de los registros de la GPU (más alto = más detalles, más sobrecarga)</string>
|
||||
<string name="gpu_log_vulkan_calls">Registros de llamadas del API de Vulkan</string>
|
||||
|
|
|
|||
|
|
@ -525,7 +525,6 @@
|
|||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">Journalisation GPU</string>
|
||||
<string name="gpu_logging_enabled">Activer la journalisation GPU</string>
|
||||
<string name="gpu_log_level">Niveau de journalisation</string>
|
||||
<string name="gpu_log_vulkan_calls">Journaliser les appels API Vulkan</string>
|
||||
<string name="gpu_log_shader_dumps">Extraire les shaders</string>
|
||||
|
|
|
|||
|
|
@ -562,8 +562,6 @@
|
|||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">Ведение журнала ГПУ</string>
|
||||
<string name="gpu_logging_enabled">Включить ведение журнала ГПУ</string>
|
||||
<string name="gpu_logging_enabled_description">Записывать операции ГПУ в файл eden_gpu.log для отладки драйверов Adreno</string>
|
||||
<string name="gpu_log_level">Уровень журналирования</string>
|
||||
<string name="gpu_log_level_description">Уровень детализации логов ГПУ (больше значение = больше деталей, выше нагрузка)</string>
|
||||
<string name="gpu_log_vulkan_calls">Записывать вызовы Vulkan API</string>
|
||||
|
|
|
|||
|
|
@ -565,8 +565,6 @@
|
|||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">Журналювання ГП</string>
|
||||
<string name="gpu_logging_enabled">Увімкнути журналювання ГП</string>
|
||||
<string name="gpu_logging_enabled_description">Журналювати операції ГП до eden_gpu.log для зневадження драйверів Adreno</string>
|
||||
<string name="gpu_log_level">Рівень журналювання</string>
|
||||
<string name="gpu_log_level_description">Рівень подробиць у журналі ГП (вищий = більше подробиць, більший вплив на швидкодію)</string>
|
||||
<string name="gpu_log_vulkan_calls">Записувати виклики API Vulkan</string>
|
||||
|
|
|
|||
|
|
@ -559,8 +559,6 @@
|
|||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">GPU 日志</string>
|
||||
<string name="gpu_logging_enabled">启用 GPU 日志</string>
|
||||
<string name="gpu_logging_enabled_description">将 GPU 操作记录至 eden_gpu.log 以供调试 Adreno 驱动</string>
|
||||
<string name="gpu_log_level">日志等级</string>
|
||||
<string name="gpu_log_level_description">GPU 日志的详细级别(数值越高 = 细节越多,开销越大)</string>
|
||||
<string name="gpu_log_vulkan_calls">记录 Vulkan API 调用</string>
|
||||
|
|
|
|||
|
|
@ -575,14 +575,16 @@
|
|||
|
||||
<!-- GPU Logging strings -->
|
||||
<string name="gpu_logging_header">GPU Logging</string>
|
||||
<string name="gpu_logging_enabled">Enable GPU Logging</string>
|
||||
<string name="gpu_logging_enabled_description">Log GPU operations to eden_gpu.log for debugging Adreno drivers</string>
|
||||
<string name="gpu_log_level">Log Level</string>
|
||||
<string name="gpu_log_level_description">Detail level for GPU logs (higher = more detail, more overhead)</string>
|
||||
<string name="gpu_log_vulkan_calls">Log Vulkan API Calls</string>
|
||||
<string name="gpu_log_vulkan_calls_description">Track all Vulkan API calls in ring buffer</string>
|
||||
<string name="gpu_log_shader_dumps">Dump Shaders</string>
|
||||
<string name="gpu_log_shader_dumps_description">Save compiled shader SPIR-V to files</string>
|
||||
<string name="gpu_log_shader_dumps">Dump SPIR-V Shaders</string>
|
||||
<string name="gpu_log_shader_dumps_description">Save recompiled SPIR-V binaries (.spv) to dump folder. Inspect with spirv-dis/spirv-cross/spirv-val.</string>
|
||||
<string name="dump_guest_shaders">Dump Guest (Maxwell) Shaders</string>
|
||||
<string name="dump_guest_shaders_description">Save Maxwell guest shader bytecode files (*.ash) to dump folder. Inspect with nvdisasm.</string>
|
||||
<string name="dump_macros">Dump Maxwell Macros</string>
|
||||
<string name="dump_macros_description">Save Maxwell macro program files (*.macro) to dump folder. Inspect with envydis.</string>
|
||||
<string name="gpu_log_memory_tracking">Track GPU Memory</string>
|
||||
<string name="gpu_log_memory_tracking_description">Monitor GPU memory allocations and deallocations</string>
|
||||
<string name="gpu_log_driver_debug">Driver Debug Info</string>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ SWITCHABLE(CpuBackend, true);
|
|||
SWITCHABLE(CpuAccuracy, true);
|
||||
SWITCHABLE(FullscreenMode, true);
|
||||
SWITCHABLE(GpuAccuracy, true);
|
||||
SWITCHABLE(GpuLogLevel, true);
|
||||
SWITCHABLE(Language, true);
|
||||
SWITCHABLE(MemoryLayout, true);
|
||||
SWITCHABLE(NvdecEmulation, false);
|
||||
|
|
@ -213,6 +212,16 @@ bool IsNceEnabled() {
|
|||
return is_nce_enabled;
|
||||
}
|
||||
|
||||
static u64 current_program_id = 0;
|
||||
|
||||
void SetCurrentProgramID(u64 program_id) {
|
||||
current_program_id = program_id;
|
||||
}
|
||||
|
||||
u64 GetCurrentProgramID() {
|
||||
return current_program_id;
|
||||
}
|
||||
|
||||
bool IsDockedMode() {
|
||||
return values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -788,8 +788,8 @@ struct Values {
|
|||
false}; // runtime_modifiable_ — startup-only
|
||||
Setting<bool> dump_exefs{linkage, false, "dump_exefs", Category::Debugging};
|
||||
Setting<bool> dump_nso{linkage, false, "dump_nso", Category::Debugging};
|
||||
Setting<bool> dump_shaders{
|
||||
linkage, false, "dump_shaders", Category::DebuggingGraphics, Specialization::Default,
|
||||
Setting<bool> dump_guest_shaders{
|
||||
linkage, false, "dump_guest_shaders", Category::DebuggingGraphics, Specialization::Default,
|
||||
false};
|
||||
Setting<bool> dump_macros{
|
||||
linkage, false, "dump_macros", Category::DebuggingGraphics, Specialization::Default, false};
|
||||
|
|
@ -813,8 +813,7 @@ struct Values {
|
|||
Setting<bool> disable_web_applet{linkage, true, "disable_web_applet", Category::Debugging};
|
||||
|
||||
// GPU Logging
|
||||
Setting<bool> gpu_logging_enabled{linkage, false, "gpu_logging_enabled", Category::Debugging};
|
||||
SwitchableSetting<GpuLogLevel> gpu_log_level{linkage, GpuLogLevel::Standard, "gpu_log_level",
|
||||
Setting<GpuLogLevel> gpu_log_level{linkage, GpuLogLevel::Off, "gpu_log_level",
|
||||
Category::Debugging};
|
||||
Setting<bool> gpu_log_vulkan_calls{linkage, true, "gpu_log_vulkan_calls", Category::Debugging};
|
||||
Setting<bool> gpu_log_shader_dumps{linkage, false, "gpu_log_shader_dumps", Category::Debugging};
|
||||
|
|
@ -876,6 +875,9 @@ bool IsFastmemEnabled();
|
|||
void SetNceEnabled(bool is_64bit);
|
||||
bool IsNceEnabled();
|
||||
|
||||
void SetCurrentProgramID(u64 program_id);
|
||||
u64 GetCurrentProgramID();
|
||||
|
||||
bool IsOpenGL();
|
||||
|
||||
bool IsDockedMode();
|
||||
|
|
|
|||
|
|
@ -326,6 +326,9 @@ struct System::Impl {
|
|||
|
||||
LOG_INFO(Core, "Loading {} ({:016X}) ...", name, params.program_id);
|
||||
|
||||
// Expose program id to dump sites and other global readers.
|
||||
Settings::SetCurrentProgramID(params.program_id);
|
||||
|
||||
// Track launch time for frontend launches
|
||||
LaunchTimestampCache::SaveLaunchTimestamp(params.program_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -296,36 +296,34 @@ void GPULogger::LogShaderCompilation(const std::string& shader_name,
|
|||
const auto log_entry = fmt::format("[{}] [Shader] Compiled: {} ({})\n",
|
||||
FormatTimestamp(timestamp), shader_name, shader_info);
|
||||
WriteToLog(log_entry);
|
||||
}
|
||||
|
||||
bool IsActive() noexcept {
|
||||
return Settings::values.gpu_log_level.GetValue() != Settings::GpuLogLevel::Off;
|
||||
}
|
||||
|
||||
void DumpSpirvShader(u64 shader_hash, std::span<const u32> spirv_code) {
|
||||
if (spirv_code.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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";
|
||||
const auto& dump_dir = GetEdenPath(EdenPath::DumpDir);
|
||||
|
||||
// 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());
|
||||
}
|
||||
// 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{
|
||||
|
|
|
|||
|
|
@ -1328,22 +1328,14 @@ Macro::Opcode MacroJITx64Impl::GetOpCode() const {
|
|||
#endif
|
||||
|
||||
static void Dump(u64 hash, std::span<const u32> code, bool decompiled = false) {
|
||||
const auto base_dir{Common::FS::GetEdenPath(Common::FS::EdenPath::DumpDir)};
|
||||
const auto macro_dir{base_dir / "macros"};
|
||||
if (!Common::FS::CreateDir(base_dir) || !Common::FS::CreateDir(macro_dir)) {
|
||||
LOG_ERROR(Common_Filesystem, "Failed to create macro dump directories");
|
||||
const auto dump_dir{Common::FS::GetEdenPath(Common::FS::EdenPath::DumpDir)};
|
||||
if (!Common::FS::CreateDir(dump_dir)) {
|
||||
LOG_ERROR(Common_Filesystem, "Failed to create dump directory");
|
||||
return;
|
||||
}
|
||||
auto name{macro_dir / fmt::format("{:016x}.macro", hash)};
|
||||
|
||||
if (decompiled) {
|
||||
auto new_name{macro_dir / fmt::format("decompiled_{:016x}.macro", hash)};
|
||||
if (Common::FS::Exists(name)) {
|
||||
(void)Common::FS::RenameFile(name, new_name);
|
||||
return;
|
||||
}
|
||||
name = new_name;
|
||||
}
|
||||
const char* const variant_suffix = decompiled ? "jit" : "raw";
|
||||
const auto name{dump_dir / fmt::format("{:016x}_{:016x}_{}.macro",
|
||||
Settings::GetCurrentProgramID(), hash, variant_suffix)};
|
||||
|
||||
std::fstream macro_file(name, std::ios::out | std::ios::binary);
|
||||
if (!macro_file) {
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
|||
const u32 cfg_offset = u32(env.StartAddress() + sizeof(Shader::ProgramHeader));
|
||||
Shader::Maxwell::Flow::CFG cfg(env, pools.flow_block, cfg_offset, index == 0);
|
||||
|
||||
if (Settings::values.dump_shaders) {
|
||||
if (Settings::values.dump_guest_shaders) {
|
||||
env.Dump(hash, key.unique_hashes[index]);
|
||||
}
|
||||
|
||||
|
|
@ -578,7 +578,7 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
|
|||
|
||||
Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
|
||||
|
||||
if (Settings::values.dump_shaders) {
|
||||
if (Settings::values.dump_guest_shaders) {
|
||||
env.Dump(hash, key.unique_hash);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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,15 +783,23 @@ 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]);
|
||||
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,
|
||||
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()) {
|
||||
const std::string name{fmt::format("Shader {:016x}", key.unique_hashes[index])};
|
||||
|
|
@ -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,14 +909,21 @@ 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);
|
||||
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,
|
||||
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()) {
|
||||
const auto name{fmt::format("Shader {:016x}", key.unique_hash)};
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/settings.h"
|
||||
#include <ranges>
|
||||
#include "shader_recompiler/environment.h"
|
||||
#include "video_core/engines/kepler_compute.h"
|
||||
|
|
@ -73,36 +74,36 @@ static Shader::TexturePixelFormat ConvertTexturePixelFormat(const Tegra::Texture
|
|||
static std::string_view StageToPrefix(Shader::Stage stage) {
|
||||
switch (stage) {
|
||||
case Shader::Stage::VertexB:
|
||||
return "VB";
|
||||
return "vs";
|
||||
case Shader::Stage::TessellationControl:
|
||||
return "TC";
|
||||
return "tc";
|
||||
case Shader::Stage::TessellationEval:
|
||||
return "TE";
|
||||
return "te";
|
||||
case Shader::Stage::Geometry:
|
||||
return "GS";
|
||||
return "gs";
|
||||
case Shader::Stage::Fragment:
|
||||
return "FS";
|
||||
return "fs";
|
||||
case Shader::Stage::Compute:
|
||||
return "CS";
|
||||
return "cs";
|
||||
case Shader::Stage::VertexA:
|
||||
return "VA";
|
||||
return "va";
|
||||
default:
|
||||
return "UK";
|
||||
return "uk";
|
||||
}
|
||||
}
|
||||
|
||||
static void DumpImpl(u64 pipeline_hash, u64 shader_hash, std::span<const u64> code,
|
||||
static void DumpImpl(u64 /*pipeline_hash*/, u64 shader_hash, std::span<const u64> code,
|
||||
[[maybe_unused]] u32 read_highest, [[maybe_unused]] u32 read_lowest,
|
||||
u32 initial_offset, Shader::Stage stage) {
|
||||
const auto shader_dir{Common::FS::GetEdenPath(Common::FS::EdenPath::DumpDir)};
|
||||
const auto base_dir{shader_dir / "shaders"};
|
||||
if (!Common::FS::CreateDir(shader_dir) || !Common::FS::CreateDir(base_dir)) {
|
||||
LOG_ERROR(Common_Filesystem, "Failed to create shader dump directories");
|
||||
const auto dump_dir{Common::FS::GetEdenPath(Common::FS::EdenPath::DumpDir)};
|
||||
if (!Common::FS::CreateDir(dump_dir)) {
|
||||
LOG_ERROR(Common_Filesystem, "Failed to create dump directory");
|
||||
return;
|
||||
}
|
||||
const auto prefix = StageToPrefix(stage);
|
||||
const auto name{base_dir /
|
||||
fmt::format("{:016x}_{}_{:016x}.ash", pipeline_hash, prefix, shader_hash)};
|
||||
const auto name{dump_dir /
|
||||
fmt::format("{:016x}_{:016x}_{}.ash",
|
||||
Settings::GetCurrentProgramID(), shader_hash, prefix)};
|
||||
std::fstream shader_file(name, std::ios::out | std::ios::binary);
|
||||
ASSERT(initial_offset % sizeof(u64) == 0);
|
||||
const size_t jump_index = initial_offset / sizeof(u64);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ VkBool32 DebugUtilCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
|||
}
|
||||
|
||||
// Route to GPU logger for tracking Vulkan validation messages
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
if (GPU::Logging::IsActive() &&
|
||||
Settings::values.gpu_log_vulkan_calls.GetValue()) {
|
||||
// Convert severity to result code for logging (negative = error)
|
||||
int result_code = 0;
|
||||
|
|
|
|||
|
|
@ -1518,7 +1518,10 @@ std::vector<VkDeviceQueueCreateInfo> Device::GetDeviceQueueCreateInfos() const {
|
|||
}
|
||||
|
||||
void Device::InitializeGPULogging() {
|
||||
if (!Settings::values.gpu_logging_enabled.GetValue()) {
|
||||
// Get log level from settings — Off is the disable.
|
||||
const auto log_level = static_cast<GPU::Logging::LogLevel>(
|
||||
static_cast<u32>(Settings::values.gpu_log_level.GetValue()));
|
||||
if (log_level == GPU::Logging::LogLevel::Off) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1532,18 +1535,12 @@ void Device::InitializeGPULogging() {
|
|||
detected_driver = GPU::Logging::DriverType::Qualcomm;
|
||||
}
|
||||
|
||||
// Get log level from settings
|
||||
const auto log_level = static_cast<GPU::Logging::LogLevel>(
|
||||
static_cast<u32>(Settings::values.gpu_log_level.GetValue()));
|
||||
|
||||
// Initialize GPU logger
|
||||
GPU::Logging::GPULogger::GetInstance().Initialize(log_level, detected_driver);
|
||||
|
||||
// Configure feature flags
|
||||
GPU::Logging::GPULogger::GetInstance().EnableVulkanCallTracking(
|
||||
Settings::values.gpu_log_vulkan_calls.GetValue());
|
||||
GPU::Logging::GPULogger::GetInstance().EnableShaderDumps(
|
||||
Settings::values.gpu_log_shader_dumps.GetValue());
|
||||
GPU::Logging::GPULogger::GetInstance().EnableMemoryTracking(
|
||||
Settings::values.gpu_log_memory_tracking.GetValue());
|
||||
GPU::Logging::GPULogger::GetInstance().EnableDriverDebugInfo(
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace Vulkan {
|
|||
: allocator{alloc}, allocation{a}, memory{info.deviceMemory},
|
||||
offset{info.offset}, size{info.size}, mapped_ptr{info.pMappedData} {
|
||||
// Log GPU memory allocation
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
if (GPU::Logging::IsActive() &&
|
||||
Settings::values.gpu_log_memory_tracking.GetValue()) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogMemoryAllocation(
|
||||
reinterpret_cast<uintptr_t>(memory),
|
||||
|
|
@ -179,7 +179,7 @@ namespace Vulkan {
|
|||
void MemoryCommit::Release() {
|
||||
if (allocation && allocator) {
|
||||
// Log GPU memory deallocation
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
if (GPU::Logging::IsActive() &&
|
||||
Settings::values.gpu_log_memory_tracking.GetValue() &&
|
||||
memory != VK_NULL_HANDLE) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogMemoryDeallocation(
|
||||
|
|
@ -243,7 +243,7 @@ namespace Vulkan {
|
|||
vk::Check(vmaCreateImage(allocator, &ci, &alloc_ci, &handle, &allocation, &alloc_info));
|
||||
|
||||
// Log GPU memory allocation for images
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
if (GPU::Logging::IsActive() &&
|
||||
Settings::values.gpu_log_memory_tracking.GetValue()) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogMemoryAllocation(
|
||||
reinterpret_cast<uintptr_t>(alloc_info.deviceMemory),
|
||||
|
|
@ -281,7 +281,7 @@ namespace Vulkan {
|
|||
vmaGetAllocationMemoryProperties(allocator, allocation, &property_flags);
|
||||
|
||||
// Log GPU memory allocation for buffers
|
||||
if (Settings::values.gpu_logging_enabled.GetValue() &&
|
||||
if (GPU::Logging::IsActive() &&
|
||||
Settings::values.gpu_log_memory_tracking.GetValue()) {
|
||||
GPU::Logging::GPULogger::GetInstance().LogMemoryAllocation(
|
||||
reinterpret_cast<uintptr_t>(alloc_info.deviceMemory),
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ void ConfigureDebug::SetConfiguration() {
|
|||
ui->enable_shader_feedback->setChecked(Settings::values.renderer_shader_feedback.GetValue());
|
||||
ui->enable_nsight_aftermath->setEnabled(runtime_lock);
|
||||
ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue());
|
||||
ui->dump_shaders->setEnabled(runtime_lock);
|
||||
ui->dump_shaders->setChecked(Settings::values.dump_shaders.GetValue());
|
||||
ui->dump_guest_shaders->setEnabled(runtime_lock);
|
||||
ui->dump_guest_shaders->setChecked(Settings::values.dump_guest_shaders.GetValue());
|
||||
ui->dump_macros->setEnabled(runtime_lock);
|
||||
ui->dump_macros->setChecked(Settings::values.dump_macros.GetValue());
|
||||
ui->disable_macro_jit->setEnabled(runtime_lock);
|
||||
|
|
@ -94,6 +94,12 @@ void ConfigureDebug::SetConfiguration() {
|
|||
Settings::values.disable_shader_loop_safety_checks.GetValue());
|
||||
ui->perform_vulkan_check->setChecked(Settings::values.perform_vulkan_check.GetValue());
|
||||
ui->debug_knobs_spinbox->setValue(Settings::values.debug_knobs.GetValue());
|
||||
|
||||
ui->gpu_log_level->setEnabled(runtime_lock);
|
||||
ui->gpu_log_level->setCurrentIndex(
|
||||
static_cast<int>(Settings::values.gpu_log_level.GetValue()));
|
||||
ui->gpu_log_shader_dumps->setEnabled(runtime_lock);
|
||||
ui->gpu_log_shader_dumps->setChecked(Settings::values.gpu_log_shader_dumps.GetValue());
|
||||
#ifdef YUZU_USE_QT_WEB_ENGINE
|
||||
ui->disable_web_applet->setChecked(Settings::values.disable_web_applet.GetValue());
|
||||
#else
|
||||
|
|
@ -123,7 +129,7 @@ void ConfigureDebug::ApplyConfiguration() {
|
|||
Settings::values.disable_buffer_reorder = ui->disable_buffer_reorder->isChecked();
|
||||
Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked();
|
||||
Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked();
|
||||
Settings::values.dump_shaders = ui->dump_shaders->isChecked();
|
||||
Settings::values.dump_guest_shaders = ui->dump_guest_shaders->isChecked();
|
||||
Settings::values.dump_macros = ui->dump_macros->isChecked();
|
||||
Settings::values.disable_shader_loop_safety_checks =
|
||||
ui->disable_loop_safety_checks->isChecked();
|
||||
|
|
@ -135,6 +141,9 @@ void ConfigureDebug::ApplyConfiguration() {
|
|||
Settings::values.serial_battery = ui->serial_battery_edit->text().toUInt();
|
||||
Settings::values.serial_unit = ui->serial_board_edit->text().toUInt();
|
||||
Settings::values.debug_knobs = ui->debug_knobs_spinbox->value();
|
||||
Settings::values.gpu_log_level =
|
||||
static_cast<Settings::GpuLogLevel>(ui->gpu_log_level->currentIndex());
|
||||
Settings::values.gpu_log_shader_dumps = ui->gpu_log_shader_dumps->isChecked();
|
||||
Debugger::ToggleConsole();
|
||||
Common::Log::Filter filter;
|
||||
filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@
|
|||
<string>Logging</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_1">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QWidget" name="logging_widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
|
|
@ -197,7 +197,77 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QWidget" name="gpu_log_level_widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="gpu_log_level_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="gpu_log_level_label">
|
||||
<property name="text">
|
||||
<string>GPU Logging/Level</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="gpu_log_level">
|
||||
<property name="toolTip">
|
||||
<string>Detail level for GPU logs. Off disables logging entirely.</string>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Errors</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Standard</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Verbose</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>All</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="toggle_console">
|
||||
<property name="text">
|
||||
<string>Show Log in Console</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="extended_logging">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
|
|
@ -210,15 +280,20 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="toggle_console">
|
||||
<property name="text">
|
||||
<string>Show Log in Console</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="1" column="3">
|
||||
<widget class="QPushButton" name="open_log_button">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open Log Location</string>
|
||||
</property>
|
||||
|
|
@ -270,7 +345,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<item row="9" column="0">
|
||||
<widget class="QCheckBox" name="dump_macros">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
|
|
@ -294,15 +369,15 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="dump_shaders">
|
||||
<widget class="QCheckBox" name="dump_guest_shaders">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</string>
|
||||
<string>When checked, it will dump original Maxwell guest shader bytecode (the input to the recompiler) as .ash files under DumpDir/shaders/. Useful for inspection with nvdisasm.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump Game Shaders</string>
|
||||
<string>Dump Guest (Maxwell) Shaders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -313,7 +388,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QCheckBox" name="disable_macro_jit">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
|
|
@ -326,7 +401,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QCheckBox" name="disable_macro_hle">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
|
|
@ -352,7 +427,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<item row="11" column="0">
|
||||
<spacer name="verticalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
|
|
@ -388,6 +463,16 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QCheckBox" name="gpu_log_shader_dumps">
|
||||
<property name="toolTip">
|
||||
<string>When checked, it will dump the recompiler's output SPIR-V binaries (.spv) under LogDir/shaders/. Inspect via SPIRV-Tools (spirv-dis / spirv-cross / spirv-val) or RenderDoc.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Dump SPIR-V Shaders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -515,6 +600,40 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QWidget" name="debug_knobs_widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_debug_knobs">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_debug_knobs">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Debug Knobs:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="debug_knobs_spinbox">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
|
|
@ -534,9 +653,9 @@
|
|||
<property name="suffix">
|
||||
<string> (bitmask)</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string>Debug Knobs: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
|
|
@ -579,7 +698,7 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<item row="20" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue