Add renderer frame capture contract

This commit is contained in:
2026-06-02 15:18:04 +02:00
parent d37145660a
commit 818014127a
9 changed files with 138 additions and 14 deletions

View File

@@ -202,6 +202,32 @@ pp::foundation::Status RecordingCommandContext::read_texture(
return pp::foundation::Status::success();
}
pp::foundation::Status RecordingCommandContext::capture_frame(
IRenderTarget& target,
IReadbackBuffer& destination) noexcept
{
if (in_render_pass_) {
return pp::foundation::Status::invalid_argument("frame capture must be outside a render pass");
}
const auto desc = target.color_desc();
const auto bytes = frame_capture_byte_size(desc);
if (!bytes) {
return bytes.status();
}
if (destination.size_bytes() < bytes.value()) {
return pp::foundation::Status::out_of_range("frame capture buffer is too small");
}
push_command(commands_, RecordedRenderCommand {
.kind = RecordedRenderCommandKind::capture_frame,
.target_desc = desc,
.capture_bytes = bytes.value(),
});
return pp::foundation::Status::success();
}
void RecordingCommandContext::end_render_pass() noexcept
{
if (!in_render_pass_) {
@@ -281,6 +307,8 @@ const char* recorded_render_command_kind_name(RecordedRenderCommandKind kind) no
return "draw";
case RecordedRenderCommandKind::read_texture:
return "read_texture";
case RecordedRenderCommandKind::capture_frame:
return "capture_frame";
case RecordedRenderCommandKind::end_render_pass:
return "end_render_pass";
case RecordedRenderCommandKind::trace_marker:

View File

@@ -14,6 +14,7 @@ enum class RecordedRenderCommandKind : std::uint8_t {
bind_mesh,
draw,
read_texture,
capture_frame,
end_render_pass,
trace_marker,
};
@@ -27,6 +28,7 @@ struct RecordedRenderCommand {
TextureDesc texture_desc {};
ReadbackRegion readback_region {};
std::uint64_t readback_bytes = 0;
std::uint64_t capture_bytes = 0;
const char* component = "";
const char* name = "";
};
@@ -91,6 +93,9 @@ public:
ITexture2D& texture,
ReadbackRegion region,
IReadbackBuffer& destination) noexcept override;
[[nodiscard]] pp::foundation::Status capture_frame(
IRenderTarget& target,
IReadbackBuffer& destination) noexcept override;
void end_render_pass() noexcept override;
[[nodiscard]] bool in_render_pass() const noexcept;

View File

@@ -231,6 +231,16 @@ pp::foundation::Result<std::uint64_t> readback_byte_size(TextureDesc desc, Readb
return pp::foundation::Result<std::uint64_t>::success(bytes);
}
pp::foundation::Result<std::uint64_t> frame_capture_byte_size(TextureDesc desc) noexcept
{
if (!desc.render_target) {
return pp::foundation::Result<std::uint64_t>::failure(
pp::foundation::Status::invalid_argument("frame capture source must be a render target"));
}
return texture_byte_size(desc);
}
const char* texture_format_name(TextureFormat format) noexcept
{
switch (format) {

View File

@@ -126,6 +126,9 @@ public:
ITexture2D& texture,
ReadbackRegion region,
IReadbackBuffer& destination) noexcept = 0;
[[nodiscard]] virtual pp::foundation::Status capture_frame(
IRenderTarget& target,
IReadbackBuffer& destination) noexcept = 0;
virtual void end_render_pass() noexcept = 0;
};
@@ -146,6 +149,7 @@ public:
[[nodiscard]] pp::foundation::Result<std::uint64_t> readback_byte_size(
TextureDesc desc,
ReadbackRegion region) noexcept;
[[nodiscard]] pp::foundation::Result<std::uint64_t> frame_capture_byte_size(TextureDesc desc) noexcept;
[[nodiscard]] pp::foundation::Status validate_readback_region(TextureDesc desc, ReadbackRegion region) noexcept;
[[nodiscard]] const char* texture_format_name(TextureFormat format) noexcept;
[[nodiscard]] const char* primitive_topology_name(PrimitiveTopology topology) noexcept;