mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-06-06 01:13:45 -04:00
[debug,dump] new dump folder/naming standard for guest/spirv shaders and macros
This commit is contained in:
parent
f28e438b0d
commit
38b4830ab0
8 changed files with 51 additions and 42 deletions
|
|
@ -212,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -869,6 +869,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -302,24 +302,22 @@ bool IsActive() noexcept {
|
|||
return Settings::values.gpu_log_level.GetValue() != Settings::GpuLogLevel::Off;
|
||||
}
|
||||
|
||||
void DumpSpirvShader(const std::string& shader_name, std::span<const u32> spirv_code) {
|
||||
void DumpSpirvShader(u64 shader_hash, std::span<const u32> spirv_code) {
|
||||
if (spirv_code.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
// Ensure parent + shaders/ exist once. CreateDir is idempotent — guarded just to
|
||||
// skip the syscall on subsequent dumps.
|
||||
static std::once_flag dirs_flag;
|
||||
std::call_once(dirs_flag, [&log_dir, &shaders_dir]() {
|
||||
[[maybe_unused]] const bool log_dir_created = CreateDir(log_dir);
|
||||
[[maybe_unused]] const bool shaders_dir_created = CreateDir(shaders_dir);
|
||||
// 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 = shaders_dir / fmt::format("{}.spv", shader_name);
|
||||
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());
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ private:
|
|||
|
||||
[[nodiscard]] bool IsActive() noexcept;
|
||||
|
||||
void DumpSpirvShader(const std::string& shader_name, std::span<const u32> spirv_code);
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -1329,22 +1329,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) {
|
||||
|
|
|
|||
|
|
@ -797,7 +797,8 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
|||
GPU::Logging::GPULogger::GetInstance().LogShaderCompilation(shader_name, shader_info);
|
||||
}
|
||||
if (should_dump) {
|
||||
GPU::Logging::DumpSpirvShader(shader_name, std::span<const u32>(code.data(), code.size()));
|
||||
GPU::Logging::DumpSpirvShader(key.unique_hashes[index],
|
||||
std::span<const u32>(code.data(), code.size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -920,7 +921,8 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
|||
GPU::Logging::GPULogger::GetInstance().LogShaderCompilation(shader_name, shader_info);
|
||||
}
|
||||
if (should_dump) {
|
||||
GPU::Logging::DumpSpirvShader(shader_name, std::span<const u32>(code.data(), code.size()));
|
||||
GPU::Logging::DumpSpirvShader(key.unique_hash,
|
||||
std::span<const u32>(code.data(), code.size()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue