devtools: show compute shader regs

This commit is contained in:
Vinicius Rangel 2024-10-16 02:04:28 -03:00
parent eddbe59793
commit 5d3c2eccd1
No known key found for this signature in database
GPG Key ID: A5B154D904B761D9
5 changed files with 130 additions and 39 deletions

View File

@ -143,7 +143,7 @@ void DebugStateImpl::PushQueueDump(QueueDump dump) {
} }
void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr, void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
const AmdGpu::Liverpool::Regs& regs) { const AmdGpu::Liverpool::Regs& regs, bool is_compute) {
std::scoped_lock lock{frame_dump_list_mutex}; std::scoped_lock lock{frame_dump_list_mutex};
const auto it = waiting_reg_dumps.find(header_addr); const auto it = waiting_reg_dumps.find(header_addr);
if (it == waiting_reg_dumps.end()) { if (it == waiting_reg_dumps.end()) {
@ -154,6 +154,14 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
waiting_reg_dumps_dbg.erase(waiting_reg_dumps_dbg.find(header_addr)); waiting_reg_dumps_dbg.erase(waiting_reg_dumps_dbg.find(header_addr));
auto& dump = frame.regs[header_addr - base_addr]; auto& dump = frame.regs[header_addr - base_addr];
dump.regs = regs; dump.regs = regs;
if (is_compute) {
dump.is_compute = true;
const auto& cs = dump.regs.cs_program;
dump.cs_data = ComputerShaderDump{
.cs_program = cs,
.code = std::vector<u32>{cs.Code().begin(), cs.Code().end()},
};
} else {
for (int i = 0; i < RegDump::MaxShaderStages; i++) { for (int i = 0; i < RegDump::MaxShaderStages; i++) {
if (regs.stage_enable.IsStageEnabled(i)) { if (regs.stage_enable.IsStageEnabled(i)) {
auto stage = regs.ProgramForStage(i); auto stage = regs.ProgramForStage(i);
@ -166,4 +174,5 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
} }
} }
} }
}
} }

View File

@ -54,10 +54,17 @@ struct ShaderDump {
std::vector<u32> code{}; std::vector<u32> code{};
}; };
struct ComputerShaderDump {
Vulkan::Liverpool::ComputeProgram cs_program{};
std::vector<u32> code{};
};
struct RegDump { struct RegDump {
bool is_compute{false};
static constexpr size_t MaxShaderStages = 5; static constexpr size_t MaxShaderStages = 5;
Vulkan::Liverpool::Regs regs{}; Vulkan::Liverpool::Regs regs{};
std::array<ShaderDump, MaxShaderStages> stages{}; std::array<ShaderDump, MaxShaderStages> stages{};
ComputerShaderDump cs_data{};
}; };
struct FrameDump { struct FrameDump {
@ -144,7 +151,7 @@ public:
void PushQueueDump(QueueDump dump); void PushQueueDump(QueueDump dump);
void PushRegsDump(uintptr_t base_addr, uintptr_t header_addr, void PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
const AmdGpu::Liverpool::Regs& regs); const AmdGpu::Liverpool::Regs& regs, bool is_compute = false);
}; };
} // namespace DebugStateType } // namespace DebugStateType

View File

@ -43,7 +43,16 @@ static std::optional<std::string> exec_cli(const char* cli) {
namespace Core::Devtools::Widget { namespace Core::Devtools::Widget {
void RegView::ProcessShader(int shader_id) { void RegView::ProcessShader(int shader_id) {
auto shader = data.stages[shader_id]; std::vector<u32> shader_code;
Vulkan::Liverpool::UserData user_data;
if (data.is_compute) {
shader_code = data.cs_data.code;
user_data = data.cs_data.cs_program.user_data;
} else {
const auto& s = data.stages[shader_id];
shader_code = s.code;
user_data = s.user_data.user_data;
}
std::string shader_dis; std::string shader_dis;
@ -60,7 +69,7 @@ void RegView::ProcessShader(int shader_id) {
} else { } else {
cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\""); cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\"");
Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write); Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write);
file.Write(shader.code); file.Write(shader_code);
file.Close(); file.Close();
auto result = exec_cli(cli.c_str()); auto result = exec_cli(cli.c_str());
@ -88,7 +97,7 @@ void RegView::ProcessShader(int shader_id) {
ShaderCache cache{ ShaderCache cache{
.hex_view = hex_view, .hex_view = hex_view,
.dis_view = dis_view, .dis_view = dis_view,
.user_data = shader.user_data.user_data, .user_data = user_data,
}; };
shader_decomp.emplace(shader_id, std::move(cache)); shader_decomp.emplace(shader_id, std::move(cache));
} }
@ -99,11 +108,48 @@ void RegView::SelectShader(int id) {
} }
} }
void RegView::DrawRegs() { void RegView::DrawComputeRegs() {
const auto& cs = data.cs_data.cs_program;
if (BeginTable("CREGS", 2, ImGuiTableFlags_Borders)) {
TableNextRow();
// clang-format off
DrawValueRowList(
"DISPATCH_INITIATOR", cs.dispatch_initiator,
"DIM_X", cs.dim_x,
"DIM_Y", cs.dim_y,
"DIM_Z", cs.dim_z,
"START_X", cs.start_x,
"START_Y", cs.start_y,
"START_Z", cs.start_z,
"NUM_THREAD_X.FULL", cs.num_thread_x.full,
"NUM_THREAD_X.PARTIAL", cs.num_thread_x.partial,
"NUM_THREAD_Y.FULL", cs.num_thread_y.full,
"NUM_THREAD_Y.PARTIAL", cs.num_thread_y.partial,
"NUM_THREAD_Z.FULL", cs.num_thread_z.full,
"NUM_THREAD_Z.PARTIAL", cs.num_thread_z.partial,
"MAX_WAVE_ID", cs.max_wave_id,
"SETTINGS.NUM_VGPRS", cs.settings.num_vgprs,
"SETTINGS.NUM_SGPRS", cs.settings.num_sgprs,
"SETTINGS.NUM_USER_REGS", cs.settings.num_user_regs,
"SETTINGS.TGID_ENABLE", cs.settings.tgid_enable,
"SETTINGS.LDS_DWORDS", cs.settings.lds_dwords,
"RESOURCE_LIMITS", cs.resource_limits
);
// clang-format on
EndTable();
}
}
void RegView::DrawGraphicsRegs() {
const auto& regs = data.regs; const auto& regs = data.regs;
if (BeginTable("REGS", 2, ImGuiTableFlags_Borders)) { if (BeginTable("REGS", 2, ImGuiTableFlags_Borders)) {
TableNextRow();
DrawValueRow("Primitive type", regs.primitive_type);
auto& s = regs.screen_scissor; auto& s = regs.screen_scissor;
DrawRow("Scissor", "(%d, %d, %d, %d)", s.top_left_x, s.top_left_y, s.bottom_right_x, DrawRow("Scissor", "(%d, %d, %d, %d)", s.top_left_x, s.top_left_y, s.bottom_right_x,
s.bottom_right_y); s.bottom_right_y);
@ -165,6 +211,18 @@ void RegView::DrawRegs() {
} }
} }
DrawRow("Primitive restart", "%X (IDX: %X)", regs.enable_primitive_restart & 1,
regs.primitive_restart_index);
// clang-format off
DrawValueRowList(
"Polygon mode", regs.polygon_control.PolyMode(),
"Cull mode", regs.polygon_control.CullingMode(),
"Clip Space", regs.clipper_control.clip_space,
"Front face", regs.polygon_control.front_face,
"Num Samples", regs.aa_config.NumSamples()
);
// clang-format on
EndTable(); EndTable();
} }
} }
@ -210,6 +268,12 @@ void RegView::SetData(DebugStateType::RegDump _data, const std::string& base_tit
this->title = fmt::format("{}/Batch {}", base_title, batch_id); this->title = fmt::format("{}/Batch {}", base_title, batch_id);
// clear cache // clear cache
shader_decomp.clear(); shader_decomp.clear();
if (data.is_compute) {
selected_shader = -2;
last_selected_cb = -1;
default_reg_popup.open = false;
ProcessShader(-2);
} else {
const auto& regs = data.regs; const auto& regs = data.regs;
if (selected_shader >= 0 && !regs.stage_enable.IsStageEnabled(selected_shader)) { if (selected_shader >= 0 && !regs.stage_enable.IsStageEnabled(selected_shader)) {
selected_shader = -1; selected_shader = -1;
@ -223,7 +287,8 @@ void RegView::SetData(DebugStateType::RegDump _data, const std::string& base_tit
default_reg_popup.SetData(title, regs.depth_buffer, regs.depth_control); default_reg_popup.SetData(title, regs.depth_buffer, regs.depth_control);
default_reg_popup.open = true; default_reg_popup.open = true;
} }
} else if (last_selected_cb >= 0 && last_selected_cb < AmdGpu::Liverpool::NumColorBuffers) { } else if (last_selected_cb >= 0 &&
last_selected_cb < AmdGpu::Liverpool::NumColorBuffers) {
const auto& buffer = regs.color_buffers[last_selected_cb]; const auto& buffer = regs.color_buffers[last_selected_cb];
const bool has_cb = buffer && regs.color_target_mask.GetMask(last_selected_cb); const bool has_cb = buffer && regs.color_target_mask.GetMask(last_selected_cb);
if (has_cb) { if (has_cb) {
@ -232,6 +297,7 @@ void RegView::SetData(DebugStateType::RegDump _data, const std::string& base_tit
} }
} }
} }
}
extra_reg_popup.clear(); extra_reg_popup.clear();
} }
@ -267,7 +333,8 @@ void RegView::Draw() {
EndMenuBar(); EndMenuBar();
} }
if (BeginChild("STAGES", {}, if (!data.is_compute &&
BeginChild("STAGES", {},
ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) { ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) {
for (int i = 0; i < DebugStateType::RegDump::MaxShaderStages; i++) { for (int i = 0; i < DebugStateType::RegDump::MaxShaderStages; i++) {
if (data.regs.stage_enable.IsStageEnabled(i)) { if (data.regs.stage_enable.IsStageEnabled(i)) {
@ -331,7 +398,11 @@ void RegView::Draw() {
if (show_registers) { if (show_registers) {
snprintf(name, sizeof(name), "Regs###reg_dump_%d/regs", id); snprintf(name, sizeof(name), "Regs###reg_dump_%d/regs", id);
if (Begin(name, &show_registers)) { if (Begin(name, &show_registers)) {
DrawRegs(); if (data.is_compute) {
DrawComputeRegs();
} else {
DrawGraphicsRegs();
}
} }
End(); End();
} }

View File

@ -37,7 +37,9 @@ class RegView {
void SelectShader(int shader_id); void SelectShader(int shader_id);
void DrawRegs(); void DrawComputeRegs();
void DrawGraphicsRegs();
public: public:
bool open = false; bool open = false;

View File

@ -446,7 +446,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
regs.cs_program.dim_z = dispatch_direct->dim_z; regs.cs_program.dim_z = dispatch_direct->dim_z;
regs.cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator; regs.cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator;
if (DebugState.DumpingCurrentReg()) { if (DebugState.DumpingCurrentReg()) {
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs); DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs,
true);
} }
if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) { if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) {
const auto cmd_address = reinterpret_cast<const void*>(header); const auto cmd_address = reinterpret_cast<const void*>(header);
@ -463,7 +464,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr; const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
const auto size = sizeof(PM4CmdDispatchIndirect::GroupDimensions); const auto size = sizeof(PM4CmdDispatchIndirect::GroupDimensions);
if (DebugState.DumpingCurrentReg()) { if (DebugState.DumpingCurrentReg()) {
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs); DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs,
true);
} }
if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) { if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) {
const auto cmd_address = reinterpret_cast<const void*>(header); const auto cmd_address = reinterpret_cast<const void*>(header);
@ -645,7 +647,7 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, int vqid) {
regs.cs_program.dim_z = dispatch_direct->dim_z; regs.cs_program.dim_z = dispatch_direct->dim_z;
regs.cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator; regs.cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator;
if (DebugState.DumpingCurrentReg()) { if (DebugState.DumpingCurrentReg()) {
DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs); DebugState.PushRegsDump(base_addr, reinterpret_cast<uintptr_t>(header), regs, true);
} }
if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) { if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) {
const auto cmd_address = reinterpret_cast<const void*>(header); const auto cmd_address = reinterpret_cast<const void*>(header);