Render target display in trace viewer.

This commit is contained in:
Ben Vanik 2015-03-21 10:41:20 -07:00
parent 494e918496
commit 7c3225ee41
3 changed files with 192 additions and 108 deletions

View File

@ -1783,7 +1783,7 @@ CommandProcessor::UpdateStatus CommandProcessor::UpdateRenderTargets() {
bool uses_stencil = bool uses_stencil =
(regs.rb_depthcontrol & 0x00000001) || (stencil_write_mask != 0); (regs.rb_depthcontrol & 0x00000001) || (stencil_write_mask != 0);
GLuint depth_target = kAnyTarget; GLuint depth_target = kAnyTarget;
if (uses_depth && uses_stencil) { if (uses_depth || uses_stencil) {
uint32_t depth_base = regs.rb_depth_info & 0xFFF; uint32_t depth_base = regs.rb_depth_info & 0xFFF;
auto depth_format = auto depth_format =
static_cast<DepthRenderTargetFormat>((regs.rb_depth_info >> 16) & 0x1); static_cast<DepthRenderTargetFormat>((regs.rb_depth_info >> 16) & 0x1);

View File

@ -83,6 +83,13 @@ class CommandProcessor {
GL4Shader* active_vertex_shader() const { return active_vertex_shader_; } GL4Shader* active_vertex_shader() const { return active_vertex_shader_; }
GL4Shader* active_pixel_shader() const { return active_pixel_shader_; } GL4Shader* active_pixel_shader() const { return active_pixel_shader_; }
GLuint GetColorRenderTarget(uint32_t pitch, xenos::MsaaSamples samples,
uint32_t base,
xenos::ColorRenderTargetFormat format);
GLuint GetDepthRenderTarget(uint32_t pitch, xenos::MsaaSamples samples,
uint32_t base,
xenos::DepthRenderTargetFormat format);
private: private:
class RingbufferReader; class RingbufferReader;
@ -204,12 +211,6 @@ class CommandProcessor {
CachedFramebuffer* GetFramebuffer(GLuint color_targets[4], CachedFramebuffer* GetFramebuffer(GLuint color_targets[4],
GLuint depth_target); GLuint depth_target);
GLuint GetColorRenderTarget(uint32_t pitch, xenos::MsaaSamples samples,
uint32_t base,
xenos::ColorRenderTargetFormat format);
GLuint GetDepthRenderTarget(uint32_t pitch, xenos::MsaaSamples samples,
uint32_t base,
xenos::DepthRenderTargetFormat format);
Memory* memory_; Memory* memory_;
uint8_t* membase_; uint8_t* membase_;

View File

@ -1458,38 +1458,32 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
const char* mode_name = "Unknown"; const char* mode_name = "Unknown";
switch (enable_mode) { switch (enable_mode) {
case ModeControl::kIgnore: case ModeControl::kIgnore:
mode_name = "Ignored"; ImGui::Text("Ignored Command %d", player.current_command_index());
break; break;
case ModeControl::kColorDepth: case ModeControl::kColorDepth:
mode_name = "Color + Depth"; case ModeControl::kDepth: {
break;
case ModeControl::kDepth:
mode_name = "Depth-only";
break;
case ModeControl::kCopy:
mode_name = "Copy";
break;
}
ImGui::Text("%s Command %d", mode_name, player.current_command_index());
static const char* kPrimNames[] = { static const char* kPrimNames[] = {
"<none>", "point list", "line list", "line strip", "<none>", "point list", "line list", "line strip",
"triangle list", "triangle fan", "triangle strip", "unknown 0x7", "triangle list", "triangle fan", "triangle strip", "unknown 0x7",
"rectangle list", "unknown 0x9", "unknown 0xA", "unknown 0xB", "rectangle list", "unknown 0x9", "unknown 0xA", "unknown 0xB",
"line loop", "quad list", "quad strip", "unknown 0xF", "line loop", "quad list", "quad strip", "unknown 0xF",
}; };
ImGui::Text("Primitive Type: %s", kPrimNames[int(draw_info.prim_type)]); ImGui::Text("%s Command %d: %s, %d indices",
ImGui::Text("Indices: %d", draw_info.index_count); enable_mode == ModeControl::kColorDepth ? "Color-Depth"
ImGui::SameLine(); : "Depth-only",
if (draw_info.is_auto_index) { player.current_command_index(),
ImGui::Text("auto-indexed"); kPrimNames[int(draw_info.prim_type)], draw_info.index_count);
} else { break;
ImGui::Text("from buffer %.8X (%db), %s, %s", draw_info.index_buffer_ptr, }
draw_info.index_buffer_size, case ModeControl::kCopy:
kIndexFormatNames[int(draw_info.index_format)], ImGui::Text("Copy Command %d", player.current_command_index());
kEndiannessNames[int(draw_info.index_endianness)]); break;
} }
if (ImGui::TreeNode("Viewport State")) { ImGui::Columns(2);
ImGui::BulletText("Viewport State:");
if (true) {
ImGui::TreePush((const void*)0);
uint32_t pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32; uint32_t pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32;
if ((pa_su_sc_mode_cntl >> 16) & 1) { if ((pa_su_sc_mode_cntl >> 16) & 1) {
uint32_t window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32; uint32_t window_offset = regs[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32;
@ -1542,24 +1536,23 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
vport_xscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32 : 1, vport_xscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32 : 1,
vport_yscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32 : 1, vport_yscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32 : 1,
vport_zscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32 : 1); vport_zscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32 : 1);
ImGui::BulletText("XY Vertex Format: %s", ((vte_control >> 8) & 0x1) ImGui::BulletText("Vertex Format: %s, %s, %s, %s",
? "premultipied by 1/w0" ((vte_control >> 8) & 0x1) ? "x/w0" : "x",
: "unmultiplied"); ((vte_control >> 8) & 0x1) ? "y/w0" : "y",
ImGui::BulletText("Z Vertex Format: %s", ((vte_control >> 9) & 0x1) ((vte_control >> 9) & 0x1) ? "z/w0" : "z",
? "premultipied by 1/w0" ((vte_control >> 10) & 0x1) ? "w0" : "1/w0");
: "unmultiplied");
ImGui::BulletText("W0 Vertex Format: %s", ((vte_control >> 10) & 0x1)
? "w0 is not 1/w0"
: "already divided");
uint32_t clip_control = regs[XE_GPU_REG_PA_CL_CLIP_CNTL].u32; uint32_t clip_control = regs[XE_GPU_REG_PA_CL_CLIP_CNTL].u32;
bool clip_enabled = ((clip_control >> 17) & 0x1) == 0; bool clip_enabled = ((clip_control >> 17) & 0x1) == 0;
ImGui::BulletText("Clip Enabled: %s", clip_enabled ? "true" : "false");
bool dx_clip = ((clip_control >> 20) & 0x1) == 0x1; bool dx_clip = ((clip_control >> 20) & 0x1) == 0x1;
ImGui::BulletText("DX Clip: %s", dx_clip ? "true" : "false"); ImGui::BulletText("Clip Enabled: %s, DX Clip: %s",
clip_enabled ? "true" : "false",
dx_clip ? "true" : "false");
ImGui::TreePop(); ImGui::TreePop();
} }
ImGui::NextColumn();
if (ImGui::TreeNode("Rasterizer State")) { ImGui::BulletText("Rasterizer State:");
if (true) {
ImGui::TreePush((const void*)0);
uint32_t pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32; uint32_t pa_su_sc_mode_cntl = regs[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32;
uint32_t pa_sc_screen_scissor_tl = uint32_t pa_sc_screen_scissor_tl =
regs[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_TL].u32; regs[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_TL].u32;
@ -1615,14 +1608,51 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
} }
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Blend State")) { ImGui::Columns(1);
auto rb_surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO].u32;
uint32_t surface_pitch = rb_surface_info & 0x3FFF;
auto surface_msaa = static_cast<MsaaSamples>((rb_surface_info >> 16) & 0x3);
if (ImGui::CollapsingHeader("Color Targets")) {
if (enable_mode != ModeControl::kDepth) {
// Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE
// if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard;
uint32_t color_control = regs[XE_GPU_REG_RB_COLORCONTROL].u32;
if ((color_control & 0x4) != 0) {
ImGui::BulletText("Alpha Test: %s %.2f",
kCompareFuncNames[color_control & 0x7],
regs[XE_GPU_REG_RB_ALPHA_REF].f32);
} else {
ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored);
ImGui::BulletText("Alpha Test: disabled");
ImGui::PopStyleColor();
}
auto blend_color = ImVec4(regs[XE_GPU_REG_RB_BLEND_RED].f32,
regs[XE_GPU_REG_RB_BLEND_GREEN].f32,
regs[XE_GPU_REG_RB_BLEND_BLUE].f32,
regs[XE_GPU_REG_RB_BLEND_ALPHA].f32);
ImGui::BulletText("Blend Color: (%.2f,%.2f,%.2f,%.2f)", blend_color.x,
blend_color.y, blend_color.z, blend_color.w);
ImGui::SameLine();
ImGui::ColorButton(blend_color, true);
uint32_t rb_color_mask = regs[XE_GPU_REG_RB_COLOR_MASK].u32;
uint32_t color_info[4] = {
regs[XE_GPU_REG_RB_COLOR_INFO].u32,
regs[XE_GPU_REG_RB_COLOR1_INFO].u32,
regs[XE_GPU_REG_RB_COLOR2_INFO].u32,
regs[XE_GPU_REG_RB_COLOR3_INFO].u32,
};
uint32_t rb_blendcontrol[4] = { uint32_t rb_blendcontrol[4] = {
regs[XE_GPU_REG_RB_BLENDCONTROL_0].u32, regs[XE_GPU_REG_RB_BLENDCONTROL_0].u32,
regs[XE_GPU_REG_RB_BLENDCONTROL_1].u32, regs[XE_GPU_REG_RB_BLENDCONTROL_1].u32,
regs[XE_GPU_REG_RB_BLENDCONTROL_2].u32, regs[XE_GPU_REG_RB_BLENDCONTROL_2].u32,
regs[XE_GPU_REG_RB_BLENDCONTROL_3].u32, regs[XE_GPU_REG_RB_BLENDCONTROL_3].u32,
}; };
for (int i = 0; i < poly::countof(rb_blendcontrol); ++i) { ImGui::Columns(2);
for (int i = 0; i < poly::countof(color_info); ++i) {
uint32_t blend_control = rb_blendcontrol[i]; uint32_t blend_control = rb_blendcontrol[i];
// A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND // A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND
auto src_blend = (blend_control & 0x0000001F) >> 0; auto src_blend = (blend_control & 0x0000001F) >> 0;
@ -1661,34 +1691,69 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
ImGui::BulletText("Blend %d: disabled", i); ImGui::BulletText("Blend %d: disabled", i);
ImGui::PopStyleColor(); ImGui::PopStyleColor();
} }
} ImGui::NextColumn();
auto blend_color = ImVec4(regs[XE_GPU_REG_RB_BLEND_RED].f32, uint32_t write_mask = (rb_color_mask >> (i * 4)) & 0xF;
regs[XE_GPU_REG_RB_BLEND_GREEN].f32, if (write_mask) {
regs[XE_GPU_REG_RB_BLEND_BLUE].f32, ImGui::BulletText("Write Mask %d: %s, %s, %s, %s", i,
regs[XE_GPU_REG_RB_BLEND_ALPHA].f32); !!(write_mask & 0x1) ? "true" : "false",
ImGui::BulletText("Blend Color: (%.2f,%.2f,%.2f,%.2f)", blend_color.x, !!(write_mask & 0x2) ? "true" : "false",
blend_color.y, blend_color.z, blend_color.w); !!(write_mask & 0x4) ? "true" : "false",
ImGui::SameLine(); !!(write_mask & 0x8) ? "true" : "false");
ImGui::ColorButton(blend_color, true);
// Alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE
// if(ALPHATESTENABLE && frag_out.a [<=/ALPHAFUNC] ALPHAREF) discard;
uint32_t color_control = regs[XE_GPU_REG_RB_COLORCONTROL].u32;
if ((color_control & 0x4) != 0) {
ImGui::BulletText("Alpha Test: %s %.2f",
kCompareFuncNames[color_control & 0x7],
regs[XE_GPU_REG_RB_ALPHA_REF].f32);
} else { } else {
ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored); ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored);
ImGui::BulletText("Alpha Test: disabled"); ImGui::BulletText("Write Mask %d: disabled", i);
ImGui::PopStyleColor(); ImGui::PopStyleColor();
} }
ImGui::NextColumn();
ImGui::TreePop();
} }
if (ImGui::TreeNode("Depth-Stencil State")) { ImGui::Columns(1);
ImGui::Columns(4);
for (int i = 0; i < poly::countof(color_info); ++i) {
uint32_t write_mask = (rb_color_mask >> (i * 4)) & 0xF;
uint32_t color_base = color_info[i] & 0xFFF;
auto color_format =
static_cast<ColorRenderTargetFormat>((color_info[i] >> 16) & 0xF);
ImVec2 button_size(256, 256);
if (write_mask) {
GLuint color_target = cp->GetColorRenderTarget(
surface_pitch, surface_msaa, color_base, color_format);
if (ImGui::ImageButton(ImTextureID(GLuint64(color_target)),
button_size, ImVec2(0, 0), ImVec2(1, 1))) {
// show viewer
}
} else {
ImGui::ImageButton(ImTextureID(GLuint64(0)), button_size,
ImVec2(0, 0), ImVec2(1, 1), -1, ImVec4(0, 0, 0, 0),
ImVec4(0, 0, 0, 0));
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Color Target %d (%s), base %.4X, pitch %d", i,
write_mask ? "enabled" : "disabled", color_base,
surface_pitch);
}
ImGui::NextColumn();
}
ImGui::Columns(1);
} else {
ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored);
ImGui::Text("Depth-only mode, no color targets");
ImGui::PopStyleColor();
}
}
if (ImGui::CollapsingHeader("Depth/Stencil Target")) {
auto rb_depthcontrol = regs[XE_GPU_REG_RB_DEPTHCONTROL].u32; auto rb_depthcontrol = regs[XE_GPU_REG_RB_DEPTHCONTROL].u32;
auto rb_stencilrefmask = regs[XE_GPU_REG_RB_STENCILREFMASK].u32; auto rb_stencilrefmask = regs[XE_GPU_REG_RB_STENCILREFMASK].u32;
auto rb_depth_info = regs[XE_GPU_REG_RB_DEPTH_INFO].u32;
bool uses_depth =
(rb_depthcontrol & 0x00000002) || (rb_depthcontrol & 0x00000004);
uint32_t stencil_write_mask = (rb_stencilrefmask & 0x00FF0000) >> 16;
bool uses_stencil =
(rb_depthcontrol & 0x00000001) || (stencil_write_mask != 0);
ImGui::Columns(2);
if (rb_depthcontrol & 0x00000002) { if (rb_depthcontrol & 0x00000002) {
ImGui::BulletText("Depth Test: enabled"); ImGui::BulletText("Depth Test: enabled");
} else { } else {
@ -1718,7 +1783,25 @@ void DrawStateUI(xe::ui::MainWindow* window, TracePlayer& player,
if (!(rb_depthcontrol & 0x00000001)) { if (!(rb_depthcontrol & 0x00000001)) {
ImGui::PopStyleColor(); ImGui::PopStyleColor();
} }
ImGui::TreePop();
ImGui::NextColumn();
if (uses_depth || uses_stencil) {
uint32_t depth_base = rb_depth_info & 0xFFF;
auto depth_format =
static_cast<DepthRenderTargetFormat>((rb_depth_info >> 16) & 0x1);
GLuint depth_target = cp->GetDepthRenderTarget(
surface_pitch, surface_msaa, depth_base, depth_format);
ImVec2 button_size(256, 256);
if (ImGui::ImageButton(ImTextureID(GLuint64(depth_target)), button_size,
ImVec2(0, 0), ImVec2(1, 1))) {
// show viewer
}
} else {
ImGui::Text("No depth target");
}
ImGui::Columns(1);
} }
if (ImGui::CollapsingHeader("Vertex Shader")) { if (ImGui::CollapsingHeader("Vertex Shader")) {