Capture renderer draw mesh inputs

This commit is contained in:
2026-06-02 16:01:29 +02:00
parent 952a00e7d3
commit 881b5271a2
7 changed files with 29 additions and 14 deletions

View File

@@ -289,12 +289,12 @@ Known local toolchain state:
sampler-state binding, texture-upload byte counts, readback bounds, sampler-state binding, texture-upload byte counts, readback bounds,
frame-capture sources, destination buffer sizes, and render-target blit frame-capture sources, destination buffer sizes, and render-target blit
regions, records render/scissor/depth/blend/texture-bind/sampler-bind/upload/ regions, records render/scissor/depth/blend/texture-bind/sampler-bind/upload/
readback/frame-capture/blit commands, and records trace markers without a readback/frame-capture/blit commands, draw mesh inputs, and records trace
window or GL context. markers without a window or GL context.
- `pano_cli record-render` exposes the recording renderer through JSON - `pano_cli record-render` exposes the recording renderer through JSON
automation, including scissor/depth/blend/texture-bind/sampler-bind/upload/ automation, including scissor/depth/blend/texture-bind/sampler-bind/upload/
readback/frame-capture/blit command and byte totals, and is covered by readback/frame-capture/blit command and byte totals plus draw vertex/index
`pano_cli_record_render_smoke` plus totals, and is covered by `pano_cli_record_render_smoke` plus
`pano_cli_record_render_rejects_oversized_target`. `pano_cli_record_render_rejects_oversized_target`.
- `pano_cli simulate-document-history` exposes `pp_document::DocumentHistory` - `pano_cli simulate-document-history` exposes `pp_document::DocumentHistory`
apply/undo/redo state through JSON automation and is covered by apply/undo/redo state through JSON automation and is covered by

View File

@@ -725,7 +725,7 @@ Results:
command-order validation, render-target blit validation, texture-slot binding command-order validation, render-target blit validation, texture-slot binding
validation, blend-state validation, scissor-state validation, recording validation, blend-state validation, scissor-state validation, recording
scissor/depth/blend/texture/sampler-bind/upload/readback/frame-capture/blit scissor/depth/blend/texture/sampler-bind/upload/readback/frame-capture/blit
command capture, and invalid catalog rejection. command capture, draw mesh-input capture, and invalid catalog rejection.
- `pp_paint_renderer_compositor_tests` passed. - `pp_paint_renderer_compositor_tests` passed.
- `pp_ui_core_color_tests` passed. - `pp_ui_core_color_tests` passed.
- `pp_ui_core_layout_value_tests` passed. - `pp_ui_core_layout_value_tests` passed.
@@ -822,14 +822,14 @@ Results:
command-order/scissor-state/depth-state/blend-state/texture-bind/ command-order/scissor-state/depth-state/blend-state/texture-bind/
sampler-bind/texture-upload/readback/frame-capture/blit validation; it sampler-bind/texture-upload/readback/frame-capture/blit validation; it
records commands, trace markers, scissor state, depth state, blend state, records commands, trace markers, scissor state, depth state, blend state,
texture/sampler binds, uploads/readbacks, frame captures, and render-target texture/sampler binds, draw mesh inputs, uploads/readbacks, frame captures,
blits, giving automation a backend-neutral render path that does not require and render-target blits, giving automation a backend-neutral render path that
a window or GL context. does not require a window or GL context.
- `pano_cli record-render` exercises that headless recording renderer and emits - `pano_cli record-render` exercises that headless recording renderer and emits
JSON command counts, target dimensions, backend name, trace/draw summary, and JSON command counts, target dimensions, backend name, trace/draw summary, and
scissor/depth/blend-state plus texture/sampler-bind/upload/readback/ draw vertex/index totals, scissor/depth/blend-state plus texture/sampler-bind/
frame-capture/blit command/byte totals for agent automation, with an upload/readback/frame-capture/blit command/byte totals for agent automation,
expected-failure smoke for oversized render/readback targets. with an expected-failure smoke for oversized render/readback targets.
- `pano_cli simulate-document-history` exercises pure document history - `pano_cli simulate-document-history` exercises pure document history
apply/undo/redo behavior and emits JSON layer/frame/history state for agent apply/undo/redo behavior and emits JSON layer/frame/history state for agent
automation. automation.

View File

@@ -96,6 +96,7 @@ pp::foundation::Status RecordingCommandContext::begin_render_pass(
in_render_pass_ = true; in_render_pass_ = true;
shader_bound_ = false; shader_bound_ = false;
mesh_bound_ = false; mesh_bound_ = false;
active_mesh_ = MeshDesc {};
push_command(commands_, RecordedRenderCommand { push_command(commands_, RecordedRenderCommand {
.kind = RecordedRenderCommandKind::begin_render_pass, .kind = RecordedRenderCommandKind::begin_render_pass,
.target_desc = active_target_, .target_desc = active_target_,
@@ -256,6 +257,7 @@ pp::foundation::Status RecordingCommandContext::bind_mesh(IMesh& mesh) noexcept
} }
mesh_bound_ = true; mesh_bound_ = true;
active_mesh_ = desc;
push_command(commands_, RecordedRenderCommand { push_command(commands_, RecordedRenderCommand {
.kind = RecordedRenderCommandKind::bind_mesh, .kind = RecordedRenderCommandKind::bind_mesh,
.mesh_desc = desc, .mesh_desc = desc,
@@ -277,6 +279,7 @@ pp::foundation::Status RecordingCommandContext::draw() noexcept
push_command(commands_, RecordedRenderCommand { push_command(commands_, RecordedRenderCommand {
.kind = RecordedRenderCommandKind::draw, .kind = RecordedRenderCommandKind::draw,
.mesh_desc = active_mesh_,
}); });
return pp::foundation::Status::success(); return pp::foundation::Status::success();
} }
@@ -421,6 +424,7 @@ void RecordingCommandContext::end_render_pass() noexcept
in_render_pass_ = false; in_render_pass_ = false;
shader_bound_ = false; shader_bound_ = false;
mesh_bound_ = false; mesh_bound_ = false;
active_mesh_ = MeshDesc {};
} }
bool RecordingCommandContext::in_render_pass() const noexcept bool RecordingCommandContext::in_render_pass() const noexcept

View File

@@ -143,6 +143,7 @@ public:
private: private:
std::vector<RecordedRenderCommand>* commands_ = nullptr; std::vector<RecordedRenderCommand>* commands_ = nullptr;
TextureDesc active_target_ {}; TextureDesc active_target_ {};
MeshDesc active_mesh_ {};
bool in_render_pass_ = false; bool in_render_pass_ = false;
bool shader_bound_ = false; bool shader_bound_ = false;
bool mesh_bound_ = false; bool mesh_bound_ = false;

View File

@@ -365,7 +365,7 @@ if(TARGET pano_cli)
COMMAND pano_cli record-render --width 32 --height 16) COMMAND pano_cli record-render --width 32 --height 16)
set_tests_properties(pano_cli_record_render_smoke PROPERTIES set_tests_properties(pano_cli_record_render_smoke PROPERTIES
LABELS "renderer;integration;desktop-fast" LABELS "renderer;integration;desktop-fast"
PASS_REGULAR_EXPRESSION "\"backend\":\"recording\".*\"width\":32.*\"height\":16.*\"commands\":16.*\"drawCommands\":1.*\"scissorCommands\":1.*\"blendCommands\":1.*\"depthCommands\":1.*\"bindTextureCommands\":1.*\"bindSamplerCommands\":1.*\"boundTextureBytes\":2048.*\"uploadCommands\":1.*\"uploadBytes\":4.*\"readbackCommands\":1.*\"readbackBytes\":2048.*\"captureCommands\":1.*\"captureBytes\":2048.*\"blitCommands\":1.*\"blitSourceBytes\":2048.*\"blitDestinationBytes\":2048") PASS_REGULAR_EXPRESSION "\"backend\":\"recording\".*\"width\":32.*\"height\":16.*\"commands\":16.*\"drawCommands\":1.*\"drawVertices\":3.*\"drawIndices\":3.*\"scissorCommands\":1.*\"blendCommands\":1.*\"depthCommands\":1.*\"bindTextureCommands\":1.*\"bindSamplerCommands\":1.*\"boundTextureBytes\":2048.*\"uploadCommands\":1.*\"uploadBytes\":4.*\"readbackCommands\":1.*\"readbackBytes\":2048.*\"captureCommands\":1.*\"captureBytes\":2048.*\"blitCommands\":1.*\"blitSourceBytes\":2048.*\"blitDestinationBytes\":2048")
add_test(NAME pano_cli_record_render_rejects_oversized_target add_test(NAME pano_cli_record_render_rejects_oversized_target
COMMAND "${CMAKE_COMMAND}" COMMAND "${CMAKE_COMMAND}"

View File

@@ -878,7 +878,7 @@ void recording_renderer_records_valid_command_sequences(pp::tests::Harness& h)
.render_target = true, .render_target = true,
}); });
RecordingShaderProgram shader("recorded-shader"); RecordingShaderProgram shader("recorded-shader");
RecordingMesh mesh(MeshDesc { .vertex_count = 3, .index_count = 0, .topology = PrimitiveTopology::triangles }); RecordingMesh mesh(MeshDesc { .vertex_count = 3, .index_count = 3, .topology = PrimitiveTopology::triangles });
PP_EXPECT(h, device.backend_name() == std::string_view("recording")); PP_EXPECT(h, device.backend_name() == std::string_view("recording"));
device.trace()->marker("renderer", "frame"); device.trace()->marker("renderer", "frame");
@@ -952,7 +952,11 @@ void recording_renderer_records_valid_command_sequences(pp::tests::Harness& h)
PP_EXPECT(h, recorded_render_command_kind_name(commands[8].kind) == std::string_view("bind_sampler")); PP_EXPECT(h, recorded_render_command_kind_name(commands[8].kind) == std::string_view("bind_sampler"));
PP_EXPECT(h, commands[9].kind == RecordedRenderCommandKind::bind_mesh); PP_EXPECT(h, commands[9].kind == RecordedRenderCommandKind::bind_mesh);
PP_EXPECT(h, commands[9].mesh_desc.vertex_count == 3U); PP_EXPECT(h, commands[9].mesh_desc.vertex_count == 3U);
PP_EXPECT(h, commands[9].mesh_desc.index_count == 3U);
PP_EXPECT(h, commands[10].kind == RecordedRenderCommandKind::draw); PP_EXPECT(h, commands[10].kind == RecordedRenderCommandKind::draw);
PP_EXPECT(h, commands[10].mesh_desc.vertex_count == 3U);
PP_EXPECT(h, commands[10].mesh_desc.index_count == 3U);
PP_EXPECT(h, commands[10].mesh_desc.topology == PrimitiveTopology::triangles);
PP_EXPECT(h, commands[11].kind == RecordedRenderCommandKind::end_render_pass); PP_EXPECT(h, commands[11].kind == RecordedRenderCommandKind::end_render_pass);
PP_EXPECT(h, recorded_render_command_kind_name(commands[10].kind) == std::string_view("draw")); PP_EXPECT(h, recorded_render_command_kind_name(commands[10].kind) == std::string_view("draw"));

View File

@@ -2237,7 +2237,7 @@ int record_render(int argc, char** argv)
pp::renderer::RecordingShaderProgram shader("pano-cli-record-render"); pp::renderer::RecordingShaderProgram shader("pano-cli-record-render");
pp::renderer::RecordingMesh mesh(pp::renderer::MeshDesc { pp::renderer::RecordingMesh mesh(pp::renderer::MeshDesc {
.vertex_count = 3, .vertex_count = 3,
.index_count = 0, .index_count = 3,
.topology = pp::renderer::PrimitiveTopology::triangles, .topology = pp::renderer::PrimitiveTopology::triangles,
}); });
@@ -2391,6 +2391,8 @@ int record_render(int argc, char** argv)
std::size_t capture_commands = 0; std::size_t capture_commands = 0;
std::size_t blit_commands = 0; std::size_t blit_commands = 0;
std::size_t trace_markers = 0; std::size_t trace_markers = 0;
std::uint64_t draw_vertices = 0;
std::uint64_t draw_indices = 0;
std::uint64_t upload_bytes = 0; std::uint64_t upload_bytes = 0;
std::uint64_t bound_texture_bytes = 0; std::uint64_t bound_texture_bytes = 0;
std::uint64_t readback_bytes = 0; std::uint64_t readback_bytes = 0;
@@ -2401,6 +2403,8 @@ int record_render(int argc, char** argv)
for (const auto& command : commands) { for (const auto& command : commands) {
if (command.kind == pp::renderer::RecordedRenderCommandKind::draw) { if (command.kind == pp::renderer::RecordedRenderCommandKind::draw) {
++draw_commands; ++draw_commands;
draw_vertices += command.mesh_desc.vertex_count;
draw_indices += command.mesh_desc.index_count;
} else if (command.kind == pp::renderer::RecordedRenderCommandKind::set_scissor) { } else if (command.kind == pp::renderer::RecordedRenderCommandKind::set_scissor) {
++scissor_commands; ++scissor_commands;
} else if (command.kind == pp::renderer::RecordedRenderCommandKind::set_blend_state) { } else if (command.kind == pp::renderer::RecordedRenderCommandKind::set_blend_state) {
@@ -2440,6 +2444,8 @@ int record_render(int argc, char** argv)
<< ",\"format\":\"rgba8\"}" << ",\"format\":\"rgba8\"}"
<< ",\"commands\":" << commands.size() << ",\"commands\":" << commands.size()
<< ",\"drawCommands\":" << draw_commands << ",\"drawCommands\":" << draw_commands
<< ",\"drawVertices\":" << draw_vertices
<< ",\"drawIndices\":" << draw_indices
<< ",\"scissorCommands\":" << scissor_commands << ",\"scissorCommands\":" << scissor_commands
<< ",\"blendCommands\":" << blend_commands << ",\"blendCommands\":" << blend_commands
<< ",\"depthCommands\":" << depth_commands << ",\"depthCommands\":" << depth_commands