mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-05 00:42:48 +00:00
devtools: frame dump: search by shader name
This commit is contained in:
parent
5c48c77ad4
commit
be2729d6cb
@ -11,6 +11,7 @@
|
||||
#include "libraries/kernel/time.h"
|
||||
#include "libraries/system/msgdialog.h"
|
||||
#include "video_core/amdgpu/pm4_cmds.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
|
||||
using namespace DebugStateType;
|
||||
|
||||
@ -168,8 +169,12 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||
if ((*dump)->regs.stage_enable.IsStageEnabled(i)) {
|
||||
auto stage = (*dump)->regs.ProgramForStage(i);
|
||||
if (stage->address_lo != 0) {
|
||||
const auto& info = AmdGpu::Liverpool::SearchBinaryInfo(stage->Address<u32*>());
|
||||
auto code = stage->Code();
|
||||
(*dump)->stages[i] = PipelineShaderProgramDump{
|
||||
.name = Vulkan::PipelineCache::GetShaderName(Shader::StageFromIndex(i),
|
||||
info.shader_hash),
|
||||
.hash = info.shader_hash,
|
||||
.user_data = *stage,
|
||||
.code = std::vector<u32>{code.begin(), code.end()},
|
||||
};
|
||||
@ -191,7 +196,10 @@ void DebugStateImpl::PushRegsDumpCompute(uintptr_t base_addr, uintptr_t header_a
|
||||
auto& cs = (*dump)->regs.cs_program;
|
||||
cs = cs_state;
|
||||
|
||||
const auto& info = AmdGpu::Liverpool::SearchBinaryInfo(cs.Address<u32*>());
|
||||
(*dump)->cs_data = PipelineComputerProgramDump{
|
||||
.name = Vulkan::PipelineCache::GetShaderName(Shader::Stage::Compute, info.shader_hash),
|
||||
.hash = info.shader_hash,
|
||||
.cs_program = cs,
|
||||
.code = std::vector<u32>{cs.Code().begin(), cs.Code().end()},
|
||||
};
|
||||
|
@ -50,11 +50,15 @@ struct QueueDump {
|
||||
};
|
||||
|
||||
struct PipelineShaderProgramDump {
|
||||
std::string name;
|
||||
u64 hash;
|
||||
Vulkan::Liverpool::ShaderProgram user_data{};
|
||||
std::vector<u32> code{};
|
||||
};
|
||||
|
||||
struct PipelineComputerProgramDump {
|
||||
std::string name;
|
||||
u64 hash;
|
||||
Vulkan::Liverpool::ComputeProgram cs_program{};
|
||||
std::vector<u32> code{};
|
||||
};
|
||||
|
@ -1174,7 +1174,7 @@ CmdListViewer::CmdListViewer(DebugStateType::FrameDump* _frame_dump,
|
||||
}
|
||||
}
|
||||
|
||||
void CmdListViewer::Draw(bool only_batches_view) {
|
||||
void CmdListViewer::Draw(bool only_batches_view, CmdListFilter& filter) {
|
||||
const auto& ctx = *GetCurrentContext();
|
||||
|
||||
if (batch_view.open) {
|
||||
@ -1285,6 +1285,41 @@ void CmdListViewer::Draw(bool only_batches_view) {
|
||||
}
|
||||
|
||||
auto& batch = std::get<BatchInfo>(event);
|
||||
|
||||
// filtering
|
||||
{
|
||||
bool remove = false;
|
||||
|
||||
if (filter.shader_name[0] != '\0') {
|
||||
remove = true;
|
||||
std::string_view shader_name{filter.shader_name};
|
||||
const auto& data = frame_dump->regs.find(batch.command_addr);
|
||||
if (data != frame_dump->regs.end()) {
|
||||
DebugStateType::RegDump& dump = data->second;
|
||||
if (dump.is_compute) {
|
||||
if (dump.cs_data.name.contains(shader_name)) {
|
||||
remove = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < DebugStateType::RegDump::MaxShaderStages; ++i) {
|
||||
if (dump.regs.stage_enable.IsStageEnabled(i)) {
|
||||
auto& stage = dump.stages[i];
|
||||
if (stage.name.contains(shader_name)) {
|
||||
remove = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (remove) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
auto const* pm4_hdr =
|
||||
reinterpret_cast<PM4Header const*>(cmdb_addr + batch.start_addr);
|
||||
|
||||
|
@ -35,6 +35,10 @@ void ParseDepthControl(u32 value, bool begin_table = true);
|
||||
void ParseEqaa(u32 value, bool begin_table = true);
|
||||
void ParseZInfo(u32 value, bool begin_table = true);
|
||||
|
||||
struct CmdListFilter {
|
||||
char shader_name[128]{};
|
||||
};
|
||||
|
||||
class CmdListViewer {
|
||||
|
||||
DebugStateType::FrameDump* frame_dump;
|
||||
@ -70,7 +74,7 @@ public:
|
||||
explicit CmdListViewer(DebugStateType::FrameDump* frame_dump, const std::vector<u32>& cmd_list,
|
||||
uintptr_t base_addr = 0, std::string name = "");
|
||||
|
||||
void Draw(bool only_batches_view = false);
|
||||
void Draw(bool only_batches_view, CmdListFilter& filter);
|
||||
};
|
||||
|
||||
} // namespace Core::Devtools::Widget
|
||||
|
@ -132,6 +132,15 @@ void FrameDumpViewer::Draw() {
|
||||
}
|
||||
}
|
||||
EndDisabled();
|
||||
SameLine();
|
||||
if (BeginMenu("Filter")) {
|
||||
|
||||
TextUnformatted("Shader name");
|
||||
SameLine();
|
||||
InputText("##filter_shader", filter.shader_name, sizeof(filter.shader_name));
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
TextEx("Submit num");
|
||||
SameLine();
|
||||
@ -187,7 +196,7 @@ void FrameDumpViewer::Draw() {
|
||||
EndGroup();
|
||||
}
|
||||
if (is_showing && selected_cmd != -1) {
|
||||
cmd_list_viewer[selected_cmd].Draw(is_collapsed);
|
||||
cmd_list_viewer[selected_cmd].Draw(is_collapsed, filter);
|
||||
}
|
||||
End();
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ class FrameDumpViewer {
|
||||
s32 selected_queue_num2;
|
||||
s32 selected_cmd = -1;
|
||||
|
||||
CmdListFilter filter;
|
||||
|
||||
public:
|
||||
bool is_open = true;
|
||||
|
||||
|
@ -292,6 +292,17 @@ void RegView::Draw() {
|
||||
EndMenuBar();
|
||||
}
|
||||
|
||||
const char* shader_name = "_";
|
||||
if (data.is_compute) {
|
||||
shader_name = data.cs_data.name.c_str();
|
||||
} else if (selected_shader >= 0) {
|
||||
shader_name = data.stages[selected_shader].name.c_str();
|
||||
}
|
||||
|
||||
TextUnformatted("Shader: ");
|
||||
SameLine();
|
||||
TextUnformatted(shader_name);
|
||||
|
||||
if (!data.is_compute &&
|
||||
BeginChild("STAGES", {},
|
||||
ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) {
|
||||
|
@ -234,12 +234,13 @@ void ShaderList::Draw() {
|
||||
}
|
||||
|
||||
InputTextEx("##search_shader", "Search by name", search_box, sizeof(search_box), {},
|
||||
ImGuiInputTextFlags_None, nullptr, nullptr);
|
||||
ImGuiInputTextFlags_None);
|
||||
|
||||
auto width = GetContentRegionAvail().x;
|
||||
int i = 0;
|
||||
for (const auto& shader : DebugState.shader_dump_list) {
|
||||
if (search_box[0] != '\0' && !shader.name.contains(search_box)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
char name[128];
|
||||
|
@ -497,7 +497,7 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::Runtim
|
||||
module = CompileSPV(spv, instance.GetDevice());
|
||||
}
|
||||
|
||||
const auto name = fmt::format("{}_{:#018x}_{}", info.stage, info.pgm_hash, perm_idx);
|
||||
const auto name = GetShaderName(info.stage, info.pgm_hash, perm_idx);
|
||||
Vulkan::SetObjectName(instance.GetDevice(), module, name);
|
||||
if (Config::collectShadersForDebug()) {
|
||||
DebugState.CollectShader(name, info.l_stage, module, spv, code,
|
||||
@ -572,6 +572,14 @@ std::optional<vk::ShaderModule> PipelineCache::ReplaceShader(vk::ShaderModule mo
|
||||
return new_module;
|
||||
}
|
||||
|
||||
std::string PipelineCache::GetShaderName(Shader::Stage stage, u64 hash,
|
||||
std::optional<size_t> perm) {
|
||||
if (perm) {
|
||||
return fmt::format("{}_{:#018x}_{}", stage, hash, *perm);
|
||||
}
|
||||
return fmt::format("{}_{:#018x}", stage, hash);
|
||||
}
|
||||
|
||||
void PipelineCache::DumpShader(std::span<const u32> code, u64 hash, Shader::Stage stage,
|
||||
size_t perm_idx, std::string_view ext) {
|
||||
if (!Config::dumpShaders()) {
|
||||
@ -583,7 +591,7 @@ void PipelineCache::DumpShader(std::span<const u32> code, u64 hash, Shader::Stag
|
||||
if (!std::filesystem::exists(dump_dir)) {
|
||||
std::filesystem::create_directories(dump_dir);
|
||||
}
|
||||
const auto filename = fmt::format("{}_{:#018x}_{}.{}", stage, hash, perm_idx, ext);
|
||||
const auto filename = fmt::format("{}.{}", GetShaderName(stage, hash, perm_idx), ext);
|
||||
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write};
|
||||
file.WriteSpan(code);
|
||||
}
|
||||
@ -597,7 +605,7 @@ std::optional<std::vector<u32>> PipelineCache::GetShaderPatch(u64 hash, Shader::
|
||||
if (!std::filesystem::exists(patch_dir)) {
|
||||
std::filesystem::create_directories(patch_dir);
|
||||
}
|
||||
const auto filename = fmt::format("{}_{:#018x}_{}.{}", stage, hash, perm_idx, ext);
|
||||
const auto filename = fmt::format("{}.{}", GetShaderName(stage, hash, perm_idx), ext);
|
||||
const auto filepath = patch_dir / filename;
|
||||
if (!std::filesystem::exists(filepath)) {
|
||||
return {};
|
||||
|
@ -65,6 +65,9 @@ public:
|
||||
std::optional<vk::ShaderModule> ReplaceShader(vk::ShaderModule module,
|
||||
std::span<const u32> spv_code);
|
||||
|
||||
static std::string GetShaderName(Shader::Stage stage, u64 hash,
|
||||
std::optional<size_t> perm = {});
|
||||
|
||||
private:
|
||||
bool RefreshGraphicsKey();
|
||||
bool RefreshComputeKey();
|
||||
|
Loading…
Reference in New Issue
Block a user