Add renderer blit command contract
This commit is contained in:
@@ -256,6 +256,52 @@ pp::foundation::Status RecordingCommandContext::capture_frame(
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status RecordingCommandContext::blit_render_target(
|
||||
IRenderTarget& source,
|
||||
ReadbackRegion source_region,
|
||||
IRenderTarget& destination,
|
||||
ReadbackRegion destination_region,
|
||||
BlitFilter filter) noexcept
|
||||
{
|
||||
if (in_render_pass_) {
|
||||
return pp::foundation::Status::invalid_argument("render target blit must be outside a render pass");
|
||||
}
|
||||
|
||||
const auto source_desc = source.color_desc();
|
||||
const auto destination_desc = destination.color_desc();
|
||||
const auto desc_status = validate_blit_descs(source_desc, destination_desc);
|
||||
if (!desc_status.ok()) {
|
||||
return desc_status;
|
||||
}
|
||||
|
||||
const auto filter_status = validate_blit_filter(filter);
|
||||
if (!filter_status.ok()) {
|
||||
return filter_status;
|
||||
}
|
||||
|
||||
const auto source_bytes = readback_byte_size(source_desc, source_region);
|
||||
if (!source_bytes) {
|
||||
return source_bytes.status();
|
||||
}
|
||||
|
||||
const auto destination_bytes = readback_byte_size(destination_desc, destination_region);
|
||||
if (!destination_bytes) {
|
||||
return destination_bytes.status();
|
||||
}
|
||||
|
||||
push_command(commands_, RecordedRenderCommand {
|
||||
.kind = RecordedRenderCommandKind::blit_render_target,
|
||||
.source_desc = source_desc,
|
||||
.destination_desc = destination_desc,
|
||||
.source_region = source_region,
|
||||
.destination_region = destination_region,
|
||||
.blit_filter = filter,
|
||||
.blit_source_bytes = source_bytes.value(),
|
||||
.blit_destination_bytes = destination_bytes.value(),
|
||||
});
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
void RecordingCommandContext::end_render_pass() noexcept
|
||||
{
|
||||
if (!in_render_pass_) {
|
||||
@@ -339,6 +385,8 @@ const char* recorded_render_command_kind_name(RecordedRenderCommandKind kind) no
|
||||
return "read_texture";
|
||||
case RecordedRenderCommandKind::capture_frame:
|
||||
return "capture_frame";
|
||||
case RecordedRenderCommandKind::blit_render_target:
|
||||
return "blit_render_target";
|
||||
case RecordedRenderCommandKind::end_render_pass:
|
||||
return "end_render_pass";
|
||||
case RecordedRenderCommandKind::trace_marker:
|
||||
|
||||
@@ -16,6 +16,7 @@ enum class RecordedRenderCommandKind : std::uint8_t {
|
||||
upload_texture,
|
||||
read_texture,
|
||||
capture_frame,
|
||||
blit_render_target,
|
||||
end_render_pass,
|
||||
trace_marker,
|
||||
};
|
||||
@@ -27,10 +28,17 @@ struct RecordedRenderCommand {
|
||||
Viewport viewport {};
|
||||
MeshDesc mesh_desc {};
|
||||
TextureDesc texture_desc {};
|
||||
TextureDesc source_desc {};
|
||||
TextureDesc destination_desc {};
|
||||
ReadbackRegion readback_region {};
|
||||
ReadbackRegion source_region {};
|
||||
ReadbackRegion destination_region {};
|
||||
BlitFilter blit_filter = BlitFilter::nearest;
|
||||
std::uint64_t upload_bytes = 0;
|
||||
std::uint64_t readback_bytes = 0;
|
||||
std::uint64_t capture_bytes = 0;
|
||||
std::uint64_t blit_source_bytes = 0;
|
||||
std::uint64_t blit_destination_bytes = 0;
|
||||
const char* component = "";
|
||||
const char* name = "";
|
||||
};
|
||||
@@ -102,6 +110,12 @@ public:
|
||||
[[nodiscard]] pp::foundation::Status capture_frame(
|
||||
IRenderTarget& target,
|
||||
IReadbackBuffer& destination) noexcept override;
|
||||
[[nodiscard]] pp::foundation::Status blit_render_target(
|
||||
IRenderTarget& source,
|
||||
ReadbackRegion source_region,
|
||||
IRenderTarget& destination,
|
||||
ReadbackRegion destination_region,
|
||||
BlitFilter filter) noexcept override;
|
||||
void end_render_pass() noexcept override;
|
||||
|
||||
[[nodiscard]] bool in_render_pass() const noexcept;
|
||||
|
||||
@@ -241,6 +241,40 @@ pp::foundation::Result<std::uint64_t> frame_capture_byte_size(TextureDesc desc)
|
||||
return texture_byte_size(desc);
|
||||
}
|
||||
|
||||
pp::foundation::Status validate_blit_filter(BlitFilter filter) noexcept
|
||||
{
|
||||
switch (filter) {
|
||||
case BlitFilter::nearest:
|
||||
case BlitFilter::linear:
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
return pp::foundation::Status::invalid_argument("blit filter is not supported");
|
||||
}
|
||||
|
||||
pp::foundation::Status validate_blit_descs(TextureDesc source, TextureDesc destination) noexcept
|
||||
{
|
||||
if (!source.render_target || !destination.render_target) {
|
||||
return pp::foundation::Status::invalid_argument("blit endpoints must be render targets");
|
||||
}
|
||||
|
||||
if (source.format != destination.format) {
|
||||
return pp::foundation::Status::invalid_argument("blit endpoints must use matching texture formats");
|
||||
}
|
||||
|
||||
const auto source_status = texture_byte_size(source);
|
||||
if (!source_status.ok()) {
|
||||
return source_status.status();
|
||||
}
|
||||
|
||||
const auto destination_status = texture_byte_size(destination);
|
||||
if (!destination_status.ok()) {
|
||||
return destination_status.status();
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
const char* texture_format_name(TextureFormat format) noexcept
|
||||
{
|
||||
switch (format) {
|
||||
@@ -269,4 +303,16 @@ const char* primitive_topology_name(PrimitiveTopology topology) noexcept
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
const char* blit_filter_name(BlitFilter filter) noexcept
|
||||
{
|
||||
switch (filter) {
|
||||
case BlitFilter::nearest:
|
||||
return "nearest";
|
||||
case BlitFilter::linear:
|
||||
return "linear";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,6 +59,11 @@ enum class PrimitiveTopology : std::uint8_t {
|
||||
lines,
|
||||
};
|
||||
|
||||
enum class BlitFilter : std::uint8_t {
|
||||
nearest,
|
||||
linear,
|
||||
};
|
||||
|
||||
struct MeshDesc {
|
||||
std::uint32_t vertex_count = 0;
|
||||
std::uint32_t index_count = 0;
|
||||
@@ -134,6 +139,12 @@ public:
|
||||
[[nodiscard]] virtual pp::foundation::Status capture_frame(
|
||||
IRenderTarget& target,
|
||||
IReadbackBuffer& destination) noexcept = 0;
|
||||
[[nodiscard]] virtual pp::foundation::Status blit_render_target(
|
||||
IRenderTarget& source,
|
||||
ReadbackRegion source_region,
|
||||
IRenderTarget& destination,
|
||||
ReadbackRegion destination_region,
|
||||
BlitFilter filter) noexcept = 0;
|
||||
virtual void end_render_pass() noexcept = 0;
|
||||
};
|
||||
|
||||
@@ -156,7 +167,12 @@ public:
|
||||
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]] pp::foundation::Status validate_blit_filter(BlitFilter filter) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_blit_descs(
|
||||
TextureDesc source,
|
||||
TextureDesc destination) noexcept;
|
||||
[[nodiscard]] const char* texture_format_name(TextureFormat format) noexcept;
|
||||
[[nodiscard]] const char* primitive_topology_name(PrimitiveTopology topology) noexcept;
|
||||
[[nodiscard]] const char* blit_filter_name(BlitFilter filter) noexcept;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user