mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 08:22:32 +00:00
devtools: show compute shader regs
This commit is contained in:
parent
eddbe59793
commit
5d3c2eccd1
@ -143,7 +143,7 @@ void DebugStateImpl::PushQueueDump(QueueDump dump) {
|
||||
}
|
||||
|
||||
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};
|
||||
const auto it = waiting_reg_dumps.find(header_addr);
|
||||
if (it == waiting_reg_dumps.end()) {
|
||||
@ -154,15 +154,24 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||
waiting_reg_dumps_dbg.erase(waiting_reg_dumps_dbg.find(header_addr));
|
||||
auto& dump = frame.regs[header_addr - base_addr];
|
||||
dump.regs = regs;
|
||||
for (int i = 0; i < RegDump::MaxShaderStages; i++) {
|
||||
if (regs.stage_enable.IsStageEnabled(i)) {
|
||||
auto stage = regs.ProgramForStage(i);
|
||||
if (stage->address_lo != 0) {
|
||||
auto code = stage->Code();
|
||||
dump.stages[i] = ShaderDump{
|
||||
.user_data = *stage,
|
||||
.code = std::vector<u32>{code.begin(), code.end()},
|
||||
};
|
||||
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++) {
|
||||
if (regs.stage_enable.IsStageEnabled(i)) {
|
||||
auto stage = regs.ProgramForStage(i);
|
||||
if (stage->address_lo != 0) {
|
||||
auto code = stage->Code();
|
||||
dump.stages[i] = ShaderDump{
|
||||
.user_data = *stage,
|
||||
.code = std::vector<u32>{code.begin(), code.end()},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,10 +54,17 @@ struct ShaderDump {
|
||||
std::vector<u32> code{};
|
||||
};
|
||||
|
||||
struct ComputerShaderDump {
|
||||
Vulkan::Liverpool::ComputeProgram cs_program{};
|
||||
std::vector<u32> code{};
|
||||
};
|
||||
|
||||
struct RegDump {
|
||||
bool is_compute{false};
|
||||
static constexpr size_t MaxShaderStages = 5;
|
||||
Vulkan::Liverpool::Regs regs{};
|
||||
std::array<ShaderDump, MaxShaderStages> stages{};
|
||||
ComputerShaderDump cs_data{};
|
||||
};
|
||||
|
||||
struct FrameDump {
|
||||
@ -144,7 +151,7 @@ public:
|
||||
void PushQueueDump(QueueDump dump);
|
||||
|
||||
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
|
||||
|
||||
|
@ -43,7 +43,16 @@ static std::optional<std::string> exec_cli(const char* cli) {
|
||||
namespace Core::Devtools::Widget {
|
||||
|
||||
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;
|
||||
|
||||
@ -60,7 +69,7 @@ void RegView::ProcessShader(int shader_id) {
|
||||
} else {
|
||||
cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\"");
|
||||
Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write);
|
||||
file.Write(shader.code);
|
||||
file.Write(shader_code);
|
||||
file.Close();
|
||||
|
||||
auto result = exec_cli(cli.c_str());
|
||||
@ -88,7 +97,7 @@ void RegView::ProcessShader(int shader_id) {
|
||||
ShaderCache cache{
|
||||
.hex_view = hex_view,
|
||||
.dis_view = dis_view,
|
||||
.user_data = shader.user_data.user_data,
|
||||
.user_data = user_data,
|
||||
};
|
||||
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;
|
||||
|
||||
if (BeginTable("REGS", 2, ImGuiTableFlags_Borders)) {
|
||||
TableNextRow();
|
||||
|
||||
DrawValueRow("Primitive type", regs.primitive_type);
|
||||
auto& s = regs.screen_scissor;
|
||||
DrawRow("Scissor", "(%d, %d, %d, %d)", s.top_left_x, s.top_left_y, s.bottom_right_x,
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -210,25 +268,33 @@ void RegView::SetData(DebugStateType::RegDump _data, const std::string& base_tit
|
||||
this->title = fmt::format("{}/Batch {}", base_title, batch_id);
|
||||
// clear cache
|
||||
shader_decomp.clear();
|
||||
const auto& regs = data.regs;
|
||||
if (selected_shader >= 0 && !regs.stage_enable.IsStageEnabled(selected_shader)) {
|
||||
selected_shader = -1;
|
||||
}
|
||||
if (default_reg_popup.open) {
|
||||
if (data.is_compute) {
|
||||
selected_shader = -2;
|
||||
last_selected_cb = -1;
|
||||
default_reg_popup.open = false;
|
||||
if (last_selected_cb == depth_id) {
|
||||
const auto& has_depth =
|
||||
regs.depth_buffer.Address() != 0 && regs.depth_control.depth_enable;
|
||||
if (has_depth) {
|
||||
default_reg_popup.SetData(title, regs.depth_buffer, regs.depth_control);
|
||||
default_reg_popup.open = true;
|
||||
}
|
||||
} else if (last_selected_cb >= 0 && last_selected_cb < AmdGpu::Liverpool::NumColorBuffers) {
|
||||
const auto& buffer = regs.color_buffers[last_selected_cb];
|
||||
const bool has_cb = buffer && regs.color_target_mask.GetMask(last_selected_cb);
|
||||
if (has_cb) {
|
||||
default_reg_popup.SetData(title, buffer, last_selected_cb);
|
||||
default_reg_popup.open = true;
|
||||
ProcessShader(-2);
|
||||
} else {
|
||||
const auto& regs = data.regs;
|
||||
if (selected_shader >= 0 && !regs.stage_enable.IsStageEnabled(selected_shader)) {
|
||||
selected_shader = -1;
|
||||
}
|
||||
if (default_reg_popup.open) {
|
||||
default_reg_popup.open = false;
|
||||
if (last_selected_cb == depth_id) {
|
||||
const auto& has_depth =
|
||||
regs.depth_buffer.Address() != 0 && regs.depth_control.depth_enable;
|
||||
if (has_depth) {
|
||||
default_reg_popup.SetData(title, regs.depth_buffer, regs.depth_control);
|
||||
default_reg_popup.open = true;
|
||||
}
|
||||
} else if (last_selected_cb >= 0 &&
|
||||
last_selected_cb < AmdGpu::Liverpool::NumColorBuffers) {
|
||||
const auto& buffer = regs.color_buffers[last_selected_cb];
|
||||
const bool has_cb = buffer && regs.color_target_mask.GetMask(last_selected_cb);
|
||||
if (has_cb) {
|
||||
default_reg_popup.SetData(title, buffer, last_selected_cb);
|
||||
default_reg_popup.open = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -267,7 +333,8 @@ void RegView::Draw() {
|
||||
EndMenuBar();
|
||||
}
|
||||
|
||||
if (BeginChild("STAGES", {},
|
||||
if (!data.is_compute &&
|
||||
BeginChild("STAGES", {},
|
||||
ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) {
|
||||
for (int i = 0; i < DebugStateType::RegDump::MaxShaderStages; i++) {
|
||||
if (data.regs.stage_enable.IsStageEnabled(i)) {
|
||||
@ -331,7 +398,11 @@ void RegView::Draw() {
|
||||
if (show_registers) {
|
||||
snprintf(name, sizeof(name), "Regs###reg_dump_%d/regs", id);
|
||||
if (Begin(name, &show_registers)) {
|
||||
DrawRegs();
|
||||
if (data.is_compute) {
|
||||
DrawComputeRegs();
|
||||
} else {
|
||||
DrawGraphicsRegs();
|
||||
}
|
||||
}
|
||||
End();
|
||||
}
|
||||
|
@ -37,7 +37,9 @@ class RegView {
|
||||
|
||||
void SelectShader(int shader_id);
|
||||
|
||||
void DrawRegs();
|
||||
void DrawComputeRegs();
|
||||
|
||||
void DrawGraphicsRegs();
|
||||
|
||||
public:
|
||||
bool open = false;
|
||||
|
@ -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.dispatch_initiator = dispatch_direct->dispatch_initiator;
|
||||
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)) {
|
||||
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 size = sizeof(PM4CmdDispatchIndirect::GroupDimensions);
|
||||
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)) {
|
||||
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.dispatch_initiator = dispatch_direct->dispatch_initiator;
|
||||
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)) {
|
||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||
|
Loading…
Reference in New Issue
Block a user