diff --git a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp index 19bcf051a..6d4179b97 100644 --- a/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp +++ b/src/graphics/host_gpu/renderer/pipeline/pipelineCache.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -116,33 +115,22 @@ void DumpShaderSpirv(const char* stage_name, uint64_t shader_hash, } void DumpShaderOriginal(const char* stage_name, uint64_t shader_hash, - std::span code, const std::string& decoded_dump) { + std::span code) { if (!Config::GraphicsDebugDumpEnabled()) { return; } EXIT_IF(code.empty()); static std::atomic_int id = 0; - const auto base = Config::GetShaderLogFolder() / "original" / - fmt::format("{:04d}_new_shader_{}_{:016x}", id++, stage_name, shader_hash); - Common::File::CreateDirectories(base.parent_path()); - for (const auto& [suffix, data, size]: { - std::tuple {".bin", static_cast(code.data()), code.size_bytes()}, - std::tuple {".rdna2", static_cast(decoded_dump.data()), - decoded_dump.size()}, - }) { - if (size == 0) { - continue; - } - auto path = base; - path += suffix; - Common::File file(path); - if (file.IsInvalid()) { - const auto path_text = Common::PathToString(path); - LOGF_COLOR(Log::Color::BrightRed, "Can't create file: %s\n", path_text.c_str()); - } else { - file.Write(data, size); - } + const auto path = Config::GetShaderLogFolder() / "original" / + fmt::format("{:04d}_new_shader_{}_{:016x}.bin", id++, stage_name, shader_hash); + Common::File::CreateDirectories(path.parent_path()); + Common::File file(path); + if (file.IsInvalid()) { + const auto path_text = Common::PathToString(path); + LOGF_COLOR(Log::Color::BrightRed, "Can't create file: %s\n", path_text.c_str()); + return; } + file.Write(code.data(), code.size_bytes()); } bool ValidateShaderSpirv(const char* label, uint64_t shader_hash, @@ -225,25 +213,13 @@ struct PipelineCache::ProgramCache { static constexpr std::size_t MaxStaticKeyWords = 13 + ShaderVertexInputInfo::RES_MAX * 13; - Permutation CompilePermutation(const ShaderParams& params, + Permutation CompilePermutation(const char* stage_name, const ShaderRecompiler::CompileOptions& options, ShaderRecompiler::TranslateResult translated, ShaderRecompiler::IR::ResourceSpecialization specialization, uint32_t push_data_start_dword) { - const char* stage_name = nullptr; - switch (options.stage) { - case ShaderType::Vertex: stage_name = "vs"; break; - case ShaderType::Mesh: stage_name = "ms"; break; - case ShaderType::Local: stage_name = "ls"; break; - case ShaderType::TessellationControl: stage_name = "hs"; break; - case ShaderType::TessellationEvaluation: stage_name = "ds"; break; - case ShaderType::Pixel: stage_name = "ps"; break; - case ShaderType::Compute: stage_name = "cs"; break; - default: EXIT("invalid pipeline shader stage\n"); - } auto result = ShaderRecompiler::CompileProgram(std::move(translated), options, specialization, push_data_start_dword); - DumpShaderOriginal(stage_name, options.shader_hash, params.code, result.decoded_dump); if (!ValidateShaderSpirv(options.dump_label, options.shader_hash, result.spirv)) { DumpShaderSpirv(stage_name, options.shader_hash, result.spirv); EXIT("%s failed hash=0x%016" PRIx64 ": SPIR-V validation failed\n", options.dump_label, @@ -321,14 +297,15 @@ struct PipelineCache::ProgramCache { stage_input.compute = &input_info; } const char* label = nullptr; + const char* stage_name = nullptr; switch (stage) { - case ShaderType::Vertex: label = "ShaderRecompiler VS"; break; - case ShaderType::Mesh: label = "ShaderRecompiler MS"; break; - case ShaderType::Local: label = "ShaderRecompiler LS"; break; - case ShaderType::TessellationControl: label = "ShaderRecompiler HS"; break; - case ShaderType::TessellationEvaluation: label = "ShaderRecompiler DS"; break; - case ShaderType::Pixel: label = "ShaderRecompiler PS"; break; - case ShaderType::Compute: label = "ShaderRecompiler CS"; break; + case ShaderType::Vertex: label = "ShaderRecompiler VS"; stage_name = "vs"; break; + case ShaderType::Mesh: label = "ShaderRecompiler MS"; stage_name = "ms"; break; + case ShaderType::Local: label = "ShaderRecompiler LS"; stage_name = "ls"; break; + case ShaderType::TessellationControl: label = "ShaderRecompiler HS"; stage_name = "hs"; break; + case ShaderType::TessellationEvaluation: label = "ShaderRecompiler DS"; stage_name = "ds"; break; + case ShaderType::Pixel: label = "ShaderRecompiler PS"; stage_name = "ps"; break; + case ShaderType::Compute: label = "ShaderRecompiler CS"; stage_name = "cs"; break; default: EXIT("invalid pipeline shader stage\n"); } ShaderRecompiler::CompileOptions options; @@ -351,6 +328,7 @@ struct PipelineCache::ProgramCache { } else { options.wave_size = input_info.wave_size; } + DumpShaderOriginal(stage_name, options.shader_hash, params.code); auto translated = ShaderRecompiler::TranslateProgram(params.code, options); if (translated.skip_dispatch) { entry = programs.try_emplace(lookup_key, ShaderRecompiler::IR::ResourcePlan {}).first; @@ -365,7 +343,7 @@ struct PipelineCache::ProgramCache { entry->second.specialization)); } entry->second.permutations.push_back(CompilePermutation( - params, options, std::move(translated), entry->second.specialization, push_data_cursor)); + stage_name, options, std::move(translated), entry->second.specialization, push_data_cursor)); const auto& permutation = entry->second.permutations.back(); input_info.stage = {.program = &permutation.program, .resources = &entry->second.resources}; permutation.program.bindings.AdvancePushData(push_data_cursor); diff --git a/src/graphics/shader/recompiler/ShaderRecompiler.cpp b/src/graphics/shader/recompiler/ShaderRecompiler.cpp index 59327498a..b930791f1 100644 --- a/src/graphics/shader/recompiler/ShaderRecompiler.cpp +++ b/src/graphics/shader/recompiler/ShaderRecompiler.cpp @@ -623,13 +623,21 @@ TranslateResult TranslateProgram(std::span code, const CompileOp IR::EliminateDeadCode(ir.blocks); } LowerTessellationMemory(ir, options); + std::string cfg_dump; + if (options.dump_ir) { + cfg_dump = CFG::GraphToString(cfg); + if (options.early_dump) { + LOGF("%s native IR before resource tracking:\n%s", GetDumpLabel(options), + MakeIrDump(cfg_dump, ir).c_str()); + } + } IR::TrackResources(ir, decoded, native_cfg); IR::EliminateDeadCode(ir.blocks); TranslateResult result; result.program = std::move(ir); if (options.dump_ir) { result.decoded_dump = std::move(decoded_dump); - result.cfg_dump = CFG::GraphToString(cfg); + result.cfg_dump = std::move(cfg_dump); } return result; }