Add renderer texture copy command
This commit is contained in:
@@ -397,6 +397,49 @@ pp::foundation::Status RecordingCommandContext::upload_texture(
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status RecordingCommandContext::copy_texture(
|
||||
ITexture2D& source,
|
||||
ReadbackRegion source_region,
|
||||
ITexture2D& destination,
|
||||
ReadbackRegion destination_region) noexcept
|
||||
{
|
||||
if (in_render_pass_) {
|
||||
return pp::foundation::Status::invalid_argument("texture copy must be outside a render pass");
|
||||
}
|
||||
|
||||
const auto source_desc = source.desc();
|
||||
const auto destination_desc = destination.desc();
|
||||
const auto desc_status = validate_texture_copy_descs(
|
||||
source_desc,
|
||||
source_region,
|
||||
destination_desc,
|
||||
destination_region);
|
||||
if (!desc_status.ok()) {
|
||||
return desc_status;
|
||||
}
|
||||
|
||||
const auto source_bytes = readback_byte_size(source_desc, source_region);
|
||||
if (!source_bytes.ok()) {
|
||||
return source_bytes.status();
|
||||
}
|
||||
|
||||
const auto destination_bytes = readback_byte_size(destination_desc, destination_region);
|
||||
if (!destination_bytes.ok()) {
|
||||
return destination_bytes.status();
|
||||
}
|
||||
|
||||
push_command(commands_, RecordedRenderCommand {
|
||||
.kind = RecordedRenderCommandKind::copy_texture,
|
||||
.source_desc = source_desc,
|
||||
.destination_desc = destination_desc,
|
||||
.source_region = source_region,
|
||||
.destination_region = destination_region,
|
||||
.copy_source_bytes = source_bytes.value(),
|
||||
.copy_destination_bytes = destination_bytes.value(),
|
||||
});
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
pp::foundation::Status RecordingCommandContext::capture_frame(
|
||||
IRenderTarget& target,
|
||||
IReadbackBuffer& destination) noexcept
|
||||
@@ -626,6 +669,8 @@ const char* recorded_render_command_kind_name(RecordedRenderCommandKind kind) no
|
||||
return "draw";
|
||||
case RecordedRenderCommandKind::upload_texture:
|
||||
return "upload_texture";
|
||||
case RecordedRenderCommandKind::copy_texture:
|
||||
return "copy_texture";
|
||||
case RecordedRenderCommandKind::read_texture:
|
||||
return "read_texture";
|
||||
case RecordedRenderCommandKind::capture_frame:
|
||||
|
||||
@@ -20,6 +20,7 @@ enum class RecordedRenderCommandKind : std::uint8_t {
|
||||
bind_mesh,
|
||||
draw,
|
||||
upload_texture,
|
||||
copy_texture,
|
||||
read_texture,
|
||||
capture_frame,
|
||||
blit_render_target,
|
||||
@@ -53,6 +54,8 @@ struct RecordedRenderCommand {
|
||||
ReadbackRegion destination_region {};
|
||||
BlitFilter blit_filter = BlitFilter::nearest;
|
||||
std::uint64_t upload_bytes = 0;
|
||||
std::uint64_t copy_source_bytes = 0;
|
||||
std::uint64_t copy_destination_bytes = 0;
|
||||
std::uint64_t readback_bytes = 0;
|
||||
std::uint64_t capture_bytes = 0;
|
||||
std::uint64_t blit_source_bytes = 0;
|
||||
@@ -138,6 +141,11 @@ public:
|
||||
ITexture2D& texture,
|
||||
ReadbackRegion region,
|
||||
std::span<const std::byte> rgba_or_channel_bytes) noexcept override;
|
||||
[[nodiscard]] pp::foundation::Status copy_texture(
|
||||
ITexture2D& source,
|
||||
ReadbackRegion source_region,
|
||||
ITexture2D& destination,
|
||||
ReadbackRegion destination_region) noexcept override;
|
||||
[[nodiscard]] pp::foundation::Status capture_frame(
|
||||
IRenderTarget& target,
|
||||
IReadbackBuffer& destination) noexcept override;
|
||||
|
||||
@@ -489,6 +489,28 @@ pp::foundation::Result<std::uint64_t> frame_capture_byte_size(TextureDesc desc)
|
||||
return texture_byte_size(desc);
|
||||
}
|
||||
|
||||
pp::foundation::Status validate_texture_copy_descs(
|
||||
TextureDesc source,
|
||||
ReadbackRegion source_region,
|
||||
TextureDesc destination,
|
||||
ReadbackRegion destination_region) noexcept
|
||||
{
|
||||
if (source.format != destination.format) {
|
||||
return pp::foundation::Status::invalid_argument("texture copy endpoints must use matching formats");
|
||||
}
|
||||
|
||||
if (source_region.width != destination_region.width || source_region.height != destination_region.height) {
|
||||
return pp::foundation::Status::invalid_argument("texture copy regions must have matching dimensions");
|
||||
}
|
||||
|
||||
const auto source_status = validate_readback_region(source, source_region);
|
||||
if (!source_status.ok()) {
|
||||
return source_status;
|
||||
}
|
||||
|
||||
return validate_readback_region(destination, destination_region);
|
||||
}
|
||||
|
||||
pp::foundation::Status validate_blit_filter(BlitFilter filter) noexcept
|
||||
{
|
||||
switch (filter) {
|
||||
|
||||
@@ -243,6 +243,11 @@ public:
|
||||
ITexture2D& texture,
|
||||
ReadbackRegion region,
|
||||
std::span<const std::byte> rgba_or_channel_bytes) noexcept = 0;
|
||||
[[nodiscard]] virtual pp::foundation::Status copy_texture(
|
||||
ITexture2D& source,
|
||||
ReadbackRegion source_region,
|
||||
ITexture2D& destination,
|
||||
ReadbackRegion destination_region) noexcept = 0;
|
||||
[[nodiscard]] virtual pp::foundation::Status capture_frame(
|
||||
IRenderTarget& target,
|
||||
IReadbackBuffer& destination) noexcept = 0;
|
||||
@@ -299,6 +304,11 @@ 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_texture_copy_descs(
|
||||
TextureDesc source,
|
||||
ReadbackRegion source_region,
|
||||
TextureDesc destination,
|
||||
ReadbackRegion destination_region) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_blit_filter(BlitFilter filter) noexcept;
|
||||
[[nodiscard]] pp::foundation::Status validate_blit_descs(
|
||||
TextureDesc source,
|
||||
|
||||
Reference in New Issue
Block a user