feat: expose D3D capture topology and per-frame draw stats in overlay

Add guest primitive-type histograms and per-frame DrawStatsSnapshot to frame capture summary so AC6 debugging can correlate point-list draws (trails) and sampler churn with native graphics planning without extra tooling.

Made-with: Cursor
This commit is contained in:
salh
2026-04-17 22:47:31 +03:00
parent 22900753d7
commit 38036d9154
3 changed files with 58 additions and 0 deletions
+19
View File
@@ -43,6 +43,25 @@ void NativeGraphicsStatusDialog::OnDraw(ImGuiIO& io) {
ImGui::Text("capture draws/clears/resolves: %u / %u / %u",
status.capture_summary.draw_count, status.capture_summary.clear_count,
status.capture_summary.resolve_count);
ImGui::Separator();
ImGui::TextUnformatted("guest draw counts (this frame, pre-reset):");
ImGui::Text(" indexed / shared / primitive: %u / %u / %u",
status.capture_summary.frame_stats.draw_calls_indexed,
status.capture_summary.frame_stats.draw_calls_indexed_shared,
status.capture_summary.frame_stats.draw_calls_primitive);
ImGui::Text(" set_sampler / set_texture_fetch: %u / %u",
status.capture_summary.frame_stats.set_sampler_state_calls,
status.capture_summary.frame_stats.set_texture_fetch_calls);
ImGui::TextUnformatted("primitive topology (D3D9 type, all draws):");
ImGui::Text(" point %u line %u strip %u tri %u triStrip %u fan %u other %u",
status.capture_summary.topology_pointlist, status.capture_summary.topology_linelist,
status.capture_summary.topology_linestrip, status.capture_summary.topology_trianglelist,
status.capture_summary.topology_trianglestrip, status.capture_summary.topology_trianglefan,
status.capture_summary.topology_other);
ImGui::Text("last draw: prim_type=%u count=%u flags=0x%X",
status.capture_summary.last_draw_primitive_type, status.capture_summary.last_draw_count,
status.capture_summary.last_draw_flags);
ImGui::Separator();
ImGui::Text("planned output: %ux%u", status.frame_plan.output_width,
status.frame_plan.output_height);
ImGui::Text("stages scene/post/ui: %s / %s / %s",
+29
View File
@@ -86,11 +86,39 @@ void HashDrawRecord(uint64_t& hash, const ac6::d3d::DrawCallRecord& draw) {
HashU32(hash, draw.shadow_state.viewport.height);
}
// D3DPRIMITIVETYPE (D3D9); used by DrawIndexed* and DrawPrimitive.
void IncrementTopologyHistogram(ac6::d3d::FrameCaptureSummary& summary, uint32_t primitive_type) {
switch (primitive_type) {
case 1:
++summary.topology_pointlist;
break;
case 2:
++summary.topology_linelist;
break;
case 3:
++summary.topology_linestrip;
break;
case 4:
++summary.topology_trianglelist;
break;
case 5:
++summary.topology_trianglestrip;
break;
case 6:
++summary.topology_trianglefan;
break;
default:
++summary.topology_other;
break;
}
}
ac6::d3d::FrameCaptureSummary MakeFrameCaptureSummary(
const ac6::d3d::FrameCaptureSnapshot& frame_capture) {
ac6::d3d::FrameCaptureSummary summary;
summary.capture_enabled = REXCVAR_GET(ac6_render_capture);
summary.frame_index = frame_capture.frame_index;
summary.frame_stats = frame_capture.stats;
summary.draw_count = static_cast<uint32_t>(frame_capture.draws.size());
summary.clear_count = static_cast<uint32_t>(frame_capture.clears.size());
summary.resolve_count = static_cast<uint32_t>(frame_capture.resolves.size());
@@ -132,6 +160,7 @@ ac6::d3d::FrameCaptureSummary MakeFrameCaptureSummary(
++summary.primitive_draw_count;
break;
}
IncrementTopologyHistogram(summary, draw.primitive_type);
uint32_t rt0 = draw.shadow_state.render_targets[0];
if (std::find(unique_rt0s.begin(), unique_rt0s.end(), rt0) == unique_rt0s.end()) {
unique_rt0s.push_back(rt0);
+10
View File
@@ -169,6 +169,16 @@ struct FrameCaptureSummary {
uint32_t indexed_draw_count{0};
uint32_t indexed_shared_draw_count{0};
uint32_t primitive_draw_count{0};
/// Per-frame guest D3D draw counters (same window as this capture; cleared each frame boundary).
DrawStatsSnapshot frame_stats{};
/// Histogram of `primitive_type` on all captured draws (D3DPRIMITIVETYPE: 1=point list … 6=fan).
uint32_t topology_pointlist{0};
uint32_t topology_linelist{0};
uint32_t topology_linestrip{0};
uint32_t topology_trianglelist{0};
uint32_t topology_trianglestrip{0};
uint32_t topology_trianglefan{0};
uint32_t topology_other{0};
uint32_t unique_rt0_count{0};
uint32_t rt0_switch_count{0};
uint32_t frame_end_render_target_count{0};