Plan OpenGL texture command metadata

This commit is contained in:
2026-06-02 20:59:05 +02:00
parent b4c2117992
commit b6a25474ff
7 changed files with 324 additions and 30 deletions

View File

@@ -46,10 +46,26 @@ pp::renderer::RecordedRenderCommand blit_command(pp::renderer::BlitFilter filter
{
pp::renderer::RecordedRenderCommand command;
command.kind = pp::renderer::RecordedRenderCommandKind::blit_render_target;
command.source_desc.format = pp::renderer::TextureFormat::rgba8;
command.destination_desc.format = pp::renderer::TextureFormat::rgba8;
command.blit_filter = filter;
return command;
}
pp::renderer::ReadbackRegion region(
std::uint32_t x,
std::uint32_t y,
std::uint32_t width,
std::uint32_t height) noexcept
{
pp::renderer::ReadbackRegion result;
result.x = x;
result.y = y;
result.width = width;
result.height = height;
return result;
}
void maps_render_pass_and_state_commands(pp::tests::Harness& h)
{
const auto begin = pp::renderer::gl::plan_recorded_render_command(pp::renderer::RecordedRenderCommand {
@@ -142,10 +158,8 @@ void maps_binding_draw_and_blit_commands(pp::tests::Harness& h)
.mesh_desc = pp::renderer::MeshDesc { .topology = pp::renderer::PrimitiveTopology::lines },
.draw_desc = pp::renderer::DrawDesc { .vertex_count = 4U, .index_count = 2U },
});
const auto blit = pp::renderer::gl::plan_recorded_render_command(pp::renderer::RecordedRenderCommand {
.kind = pp::renderer::RecordedRenderCommandKind::blit_render_target,
.blit_filter = pp::renderer::BlitFilter::linear,
});
const auto blit = pp::renderer::gl::plan_recorded_render_command(
blit_command(pp::renderer::BlitFilter::linear));
PP_EXPECT(h, texture.supported);
PP_EXPECT(h, texture.requires_render_pass);
@@ -162,6 +176,84 @@ void maps_binding_draw_and_blit_commands(pp::tests::Harness& h)
PP_EXPECT(h, blit.supported);
PP_EXPECT(h, !blit.requires_render_pass);
PP_EXPECT(h, blit.blit_filter.value == 0x2601U);
PP_EXPECT(h, blit.source_texture_format.internal_format == 0x8058U);
PP_EXPECT(h, blit.destination_texture_format.internal_format == 0x8058U);
}
void maps_texture_io_and_capture_commands(pp::tests::Harness& h)
{
pp::renderer::RecordedRenderCommand upload_command;
upload_command.kind = pp::renderer::RecordedRenderCommandKind::upload_texture;
upload_command.texture_desc.format = pp::renderer::TextureFormat::r8;
upload_command.readback_region = region(1U, 2U, 3U, 4U);
upload_command.upload_bytes = 12U;
pp::renderer::RecordedRenderCommand mipmap_command;
mipmap_command.kind = pp::renderer::RecordedRenderCommandKind::generate_mipmaps;
mipmap_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
mipmap_command.generated_mip_levels = 4U;
mipmap_command.generated_mip_bytes = 340U;
pp::renderer::RecordedRenderCommand transition_command;
transition_command.kind = pp::renderer::RecordedRenderCommandKind::transition_texture;
transition_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
transition_command.before_state = pp::renderer::TextureState::upload_destination;
transition_command.after_state = pp::renderer::TextureState::shader_read;
pp::renderer::RecordedRenderCommand copy_command;
copy_command.kind = pp::renderer::RecordedRenderCommandKind::copy_texture;
copy_command.source_desc.format = pp::renderer::TextureFormat::rgba8;
copy_command.destination_desc.format = pp::renderer::TextureFormat::r8;
copy_command.source_region = region(0U, 1U, 8U, 4U);
copy_command.destination_region = region(2U, 3U, 8U, 4U);
copy_command.copy_source_bytes = 128U;
copy_command.copy_destination_bytes = 32U;
pp::renderer::RecordedRenderCommand read_command;
read_command.kind = pp::renderer::RecordedRenderCommandKind::read_texture;
read_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
read_command.readback_region = region(4U, 5U, 6U, 7U);
read_command.readback_bytes = 168U;
pp::renderer::RecordedRenderCommand capture_command;
capture_command.kind = pp::renderer::RecordedRenderCommandKind::capture_frame;
capture_command.target_desc.format = pp::renderer::TextureFormat::rgba8;
capture_command.capture_bytes = 512U;
const auto upload = pp::renderer::gl::plan_recorded_render_command(upload_command);
const auto mipmap = pp::renderer::gl::plan_recorded_render_command(mipmap_command);
const auto transition = pp::renderer::gl::plan_recorded_render_command(transition_command);
const auto copy = pp::renderer::gl::plan_recorded_render_command(copy_command);
const auto read = pp::renderer::gl::plan_recorded_render_command(read_command);
const auto capture = pp::renderer::gl::plan_recorded_render_command(capture_command);
PP_EXPECT(h, upload.supported);
PP_EXPECT(h, upload.kind == pp::renderer::gl::OpenGlPlannedCommandKind::upload_texture);
PP_EXPECT(h, upload.texture_format.internal_format == 0x8229U);
PP_EXPECT(h, upload.readback_region.y == 2U);
PP_EXPECT(h, upload.upload_bytes == 12U);
PP_EXPECT(h, mipmap.supported);
PP_EXPECT(h, mipmap.kind == pp::renderer::gl::OpenGlPlannedCommandKind::generate_mipmaps);
PP_EXPECT(h, mipmap.generated_mip_levels == 4U);
PP_EXPECT(h, mipmap.generated_mip_bytes == 340U);
PP_EXPECT(h, transition.supported);
PP_EXPECT(h, transition.kind == pp::renderer::gl::OpenGlPlannedCommandKind::transition_texture);
PP_EXPECT(h, transition.before_state == pp::renderer::TextureState::upload_destination);
PP_EXPECT(h, transition.after_state == pp::renderer::TextureState::shader_read);
PP_EXPECT(h, copy.supported);
PP_EXPECT(h, copy.kind == pp::renderer::gl::OpenGlPlannedCommandKind::copy_texture);
PP_EXPECT(h, copy.source_texture_format.internal_format == 0x8058U);
PP_EXPECT(h, copy.destination_texture_format.internal_format == 0x8229U);
PP_EXPECT(h, copy.destination_region.x == 2U);
PP_EXPECT(h, copy.copy_source_bytes == 128U);
PP_EXPECT(h, copy.copy_destination_bytes == 32U);
PP_EXPECT(h, read.supported);
PP_EXPECT(h, read.kind == pp::renderer::gl::OpenGlPlannedCommandKind::read_texture);
PP_EXPECT(h, read.readback_region.width == 6U);
PP_EXPECT(h, read.readback_bytes == 168U);
PP_EXPECT(h, capture.supported);
PP_EXPECT(h, capture.kind == pp::renderer::gl::OpenGlPlannedCommandKind::capture_frame);
PP_EXPECT(h, capture.capture_bytes == 512U);
}
void rejects_unsupported_command_tokens(pp::tests::Harness& h)
@@ -190,10 +282,14 @@ void rejects_unsupported_command_tokens(pp::tests::Harness& h)
.topology = static_cast<pp::renderer::PrimitiveTopology>(255U),
},
});
const auto bad_blit = pp::renderer::gl::plan_recorded_render_command(pp::renderer::RecordedRenderCommand {
.kind = pp::renderer::RecordedRenderCommandKind::blit_render_target,
.blit_filter = static_cast<pp::renderer::BlitFilter>(255U),
});
const auto bad_blit = pp::renderer::gl::plan_recorded_render_command(
blit_command(static_cast<pp::renderer::BlitFilter>(255U)));
pp::renderer::RecordedRenderCommand bad_transition_command;
bad_transition_command.kind = pp::renderer::RecordedRenderCommandKind::transition_texture;
bad_transition_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
bad_transition_command.before_state = static_cast<pp::renderer::TextureState>(255U);
bad_transition_command.after_state = pp::renderer::TextureState::shader_read;
const auto bad_transition = pp::renderer::gl::plan_recorded_render_command(bad_transition_command);
const auto unknown = pp::renderer::gl::plan_recorded_render_command(pp::renderer::RecordedRenderCommand {
.kind = static_cast<pp::renderer::RecordedRenderCommandKind>(255U),
});
@@ -208,6 +304,8 @@ void rejects_unsupported_command_tokens(pp::tests::Harness& h)
PP_EXPECT(h, bad_mesh.primitive_mode == 0U);
PP_EXPECT(h, !bad_blit.supported);
PP_EXPECT(h, bad_blit.blit_filter.value == 0U);
PP_EXPECT(h, !bad_transition.supported);
PP_EXPECT(h, bad_transition.kind == pp::renderer::gl::OpenGlPlannedCommandKind::transition_texture);
PP_EXPECT(h, !unknown.supported);
PP_EXPECT(h, unknown.kind == pp::renderer::gl::OpenGlPlannedCommandKind::unknown);
}
@@ -220,6 +318,9 @@ void names_planned_command_kinds(pp::tests::Harness& h)
PP_EXPECT(h, pp::renderer::gl::planned_command_kind_name(
pp::renderer::gl::OpenGlPlannedCommandKind::passthrough)
== std::string_view("passthrough"));
PP_EXPECT(h, pp::renderer::gl::planned_command_kind_name(
pp::renderer::gl::OpenGlPlannedCommandKind::copy_texture)
== std::string_view("copy_texture"));
PP_EXPECT(h, pp::renderer::gl::planned_command_kind_name(
static_cast<pp::renderer::gl::OpenGlPlannedCommandKind>(255U))
== std::string_view("unknown"));
@@ -306,6 +407,61 @@ void tracks_unsupported_commands_in_streams(pp::tests::Harness& h)
PP_EXPECT(h, plan.commands[3].kind == pp::renderer::gl::OpenGlPlannedCommandKind::unknown);
}
void counts_typed_texture_commands_in_streams(pp::tests::Harness& h)
{
pp::renderer::RecordedRenderCommand upload_command;
upload_command.kind = pp::renderer::RecordedRenderCommandKind::upload_texture;
upload_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
upload_command.upload_bytes = 4U;
pp::renderer::RecordedRenderCommand mipmap_command;
mipmap_command.kind = pp::renderer::RecordedRenderCommandKind::generate_mipmaps;
mipmap_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
mipmap_command.generated_mip_levels = 2U;
pp::renderer::RecordedRenderCommand transition_command;
transition_command.kind = pp::renderer::RecordedRenderCommandKind::transition_texture;
transition_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
transition_command.before_state = pp::renderer::TextureState::copy_destination;
transition_command.after_state = pp::renderer::TextureState::shader_read;
pp::renderer::RecordedRenderCommand copy_command;
copy_command.kind = pp::renderer::RecordedRenderCommandKind::copy_texture;
copy_command.source_desc.format = pp::renderer::TextureFormat::rgba8;
copy_command.destination_desc.format = pp::renderer::TextureFormat::rgba8;
pp::renderer::RecordedRenderCommand read_command;
read_command.kind = pp::renderer::RecordedRenderCommandKind::read_texture;
read_command.texture_desc.format = pp::renderer::TextureFormat::rgba8;
pp::renderer::RecordedRenderCommand capture_command;
capture_command.kind = pp::renderer::RecordedRenderCommandKind::capture_frame;
capture_command.target_desc.format = pp::renderer::TextureFormat::rgba8;
const std::vector<pp::renderer::RecordedRenderCommand> commands {
upload_command,
mipmap_command,
transition_command,
copy_command,
read_command,
capture_command,
};
const auto plan = pp::renderer::gl::plan_recorded_render_commands(commands);
PP_EXPECT(h, plan.supported);
PP_EXPECT(h, plan.upload_command_count == 1U);
PP_EXPECT(h, plan.mipmap_command_count == 1U);
PP_EXPECT(h, plan.transition_command_count == 1U);
PP_EXPECT(h, plan.copy_command_count == 1U);
PP_EXPECT(h, plan.readback_command_count == 1U);
PP_EXPECT(h, plan.capture_command_count == 1U);
PP_EXPECT(h, plan.passthrough_command_count == 0U);
PP_EXPECT(h, plan.render_pass_order_error_count == 0U);
PP_EXPECT(h, plan.commands[0].kind == pp::renderer::gl::OpenGlPlannedCommandKind::upload_texture);
PP_EXPECT(h, plan.commands[5].kind == pp::renderer::gl::OpenGlPlannedCommandKind::capture_frame);
}
}
int main()
@@ -313,10 +469,12 @@ int main()
pp::tests::Harness harness;
harness.run("maps_render_pass_and_state_commands", maps_render_pass_and_state_commands);
harness.run("maps_binding_draw_and_blit_commands", maps_binding_draw_and_blit_commands);
harness.run("maps_texture_io_and_capture_commands", maps_texture_io_and_capture_commands);
harness.run("rejects_unsupported_command_tokens", rejects_unsupported_command_tokens);
harness.run("names_planned_command_kinds", names_planned_command_kinds);
harness.run("plans_valid_recorded_command_streams", plans_valid_recorded_command_streams);
harness.run("flags_broken_render_pass_command_order", flags_broken_render_pass_command_order);
harness.run("tracks_unsupported_commands_in_streams", tracks_unsupported_commands_in_streams);
harness.run("counts_typed_texture_commands_in_streams", counts_typed_texture_commands_in_streams);
return harness.finish();
}