Route RTT utility clears through GL backend

This commit is contained in:
2026-06-04 21:58:27 +02:00
parent ce787ce186
commit 4c61a490ce
7 changed files with 275 additions and 23 deletions

View File

@@ -61,6 +61,13 @@ struct RecordedOpenGlTextureParameterCall {
float value = 0.0F;
};
struct RecordedOpenGlColorMaskCall {
std::uint8_t r = 0;
std::uint8_t g = 0;
std::uint8_t b = 0;
std::uint8_t a = 0;
};
struct RecordedOpenGlFramebufferTextureCopyCall {
std::uint32_t target = 0;
std::int32_t level = 0;
@@ -205,6 +212,8 @@ std::vector<pp::renderer::gl::OpenGlViewportRect> recorded_viewport_calls;
std::vector<pp::renderer::gl::OpenGlScissorRect> recorded_scissor_calls;
std::vector<std::uint32_t> recorded_integer_queries;
std::vector<std::uint32_t> recorded_float_queries;
std::vector<std::uint32_t> recorded_boolean_queries;
std::vector<RecordedOpenGlColorMaskCall> recorded_color_mask_calls;
std::vector<std::uint32_t> recorded_active_texture_calls;
std::vector<RecordedOpenGlBindingCall> recorded_binding_calls;
std::vector<std::uint32_t> recorded_generated_texture_counts;
@@ -448,6 +457,27 @@ void record_get_float(std::uint32_t name, float* value) noexcept
}
}
void record_get_boolean(std::uint32_t name, std::uint8_t* value) noexcept
{
recorded_boolean_queries.push_back(name);
if (name == 0x0C23U) {
value[0] = 1U;
value[1] = 0U;
value[2] = 1U;
value[3] = 1U;
}
}
void record_color_mask(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a) noexcept
{
recorded_color_mask_calls.push_back(RecordedOpenGlColorMaskCall {
.r = r,
.g = g,
.b = b,
.a = a,
});
}
void record_active_texture(std::uint32_t texture_unit) noexcept
{
recorded_active_texture_calls.push_back(texture_unit);
@@ -2230,6 +2260,105 @@ void rejects_incomplete_app_clear_dispatch(pp::tests::Harness& h)
PP_EXPECT(h, status.code == pp::foundation::StatusCode::invalid_argument);
}
void clears_render_target_through_dispatch(pp::tests::Harness& h)
{
recorded_clear_calls.clear();
const auto status = pp::renderer::gl::clear_opengl_render_target(
pp::renderer::gl::OpenGlDefaultClear {
.color = { 0.2F, 0.4F, 0.6F, 0.8F },
.mask = 0x00004100U,
},
pp::renderer::gl::OpenGlClearDispatch {
.clear_color = record_clear_color,
.clear = record_clear,
});
PP_EXPECT(h, status.ok());
PP_EXPECT(h, recorded_clear_calls.size() == 2U);
PP_EXPECT(h, recorded_clear_calls[0].color[0] == 0.2F);
PP_EXPECT(h, recorded_clear_calls[0].color[1] == 0.4F);
PP_EXPECT(h, recorded_clear_calls[0].color[2] == 0.6F);
PP_EXPECT(h, recorded_clear_calls[0].color[3] == 0.8F);
PP_EXPECT(h, recorded_clear_calls[1].mask == 0x00004100U);
}
void clears_color_buffer_with_write_mask_and_restores_previous_mask(pp::tests::Harness& h)
{
recorded_boolean_queries.clear();
recorded_color_mask_calls.clear();
recorded_clear_calls.clear();
const auto status = pp::renderer::gl::clear_opengl_color_buffer_with_write_mask(
pp::renderer::gl::OpenGlColorMaskedClear {
.mask = { .r = 1U, .g = 0U, .b = 0U, .a = 1U },
.color = { 0.75F, 0.5F, 0.25F, 1.0F },
},
pp::renderer::gl::OpenGlColorMaskedClearDispatch {
.get_boolean = record_get_boolean,
.color_mask = record_color_mask,
.clear_color = record_clear_color,
.clear = record_clear,
});
PP_EXPECT(h, status.ok());
PP_EXPECT(h, recorded_boolean_queries.size() == 1U);
PP_EXPECT(h, recorded_boolean_queries[0] == 0x0C23U);
PP_EXPECT(h, recorded_color_mask_calls.size() == 2U);
PP_EXPECT(h, recorded_color_mask_calls[0].r == 1U);
PP_EXPECT(h, recorded_color_mask_calls[0].g == 0U);
PP_EXPECT(h, recorded_color_mask_calls[0].b == 0U);
PP_EXPECT(h, recorded_color_mask_calls[0].a == 1U);
PP_EXPECT(h, recorded_color_mask_calls[1].r == 1U);
PP_EXPECT(h, recorded_color_mask_calls[1].g == 0U);
PP_EXPECT(h, recorded_color_mask_calls[1].b == 1U);
PP_EXPECT(h, recorded_color_mask_calls[1].a == 1U);
PP_EXPECT(h, recorded_clear_calls.size() == 2U);
PP_EXPECT(h, recorded_clear_calls[0].color[0] == 0.75F);
PP_EXPECT(h, recorded_clear_calls[0].color[1] == 0.5F);
PP_EXPECT(h, recorded_clear_calls[0].color[2] == 0.25F);
PP_EXPECT(h, recorded_clear_calls[0].color[3] == 1.0F);
PP_EXPECT(h, recorded_clear_calls[1].mask == 0x00004000U);
}
void rejects_invalid_render_target_clear_dispatch(pp::tests::Harness& h)
{
const auto missing_clear = pp::renderer::gl::clear_opengl_render_target(
pp::renderer::gl::OpenGlDefaultClear {
.color = { 1.0F, 0.0F, 0.0F, 1.0F },
.mask = 0x00004000U,
},
pp::renderer::gl::OpenGlClearDispatch {
.clear_color = record_clear_color,
});
const auto invalid_mask = pp::renderer::gl::clear_opengl_render_target(
pp::renderer::gl::OpenGlDefaultClear {
.color = { 1.0F, 0.0F, 0.0F, 1.0F },
.mask = 0U,
},
pp::renderer::gl::OpenGlClearDispatch {
.clear_color = record_clear_color,
.clear = record_clear,
});
const auto missing_masked_dispatch = pp::renderer::gl::clear_opengl_color_buffer_with_write_mask(
pp::renderer::gl::OpenGlColorMaskedClear {
.mask = { .r = 1U, .g = 1U, .b = 1U, .a = 1U },
.color = { 1.0F, 0.0F, 0.0F, 1.0F },
},
pp::renderer::gl::OpenGlColorMaskedClearDispatch {
.get_boolean = record_get_boolean,
.clear_color = record_clear_color,
.clear = record_clear,
});
PP_EXPECT(h, !missing_clear.ok());
PP_EXPECT(h, missing_clear.code == pp::foundation::StatusCode::invalid_argument);
PP_EXPECT(h, !invalid_mask.ok());
PP_EXPECT(h, invalid_mask.code == pp::foundation::StatusCode::invalid_argument);
PP_EXPECT(h, !missing_masked_dispatch.ok());
PP_EXPECT(h, missing_masked_dispatch.code == pp::foundation::StatusCode::invalid_argument);
}
void applies_viewport_dispatch(pp::tests::Harness& h)
{
recorded_viewport_calls.clear();
@@ -5122,6 +5251,9 @@ int main()
harness.run("rejects_incomplete_capability_detection_dispatch", rejects_incomplete_capability_detection_dispatch);
harness.run("clears_app_default_target", clears_app_default_target);
harness.run("rejects_incomplete_app_clear_dispatch", rejects_incomplete_app_clear_dispatch);
harness.run("clears_render_target_through_dispatch", clears_render_target_through_dispatch);
harness.run("clears_color_buffer_with_write_mask_and_restores_previous_mask", clears_color_buffer_with_write_mask_and_restores_previous_mask);
harness.run("rejects_invalid_render_target_clear_dispatch", rejects_invalid_render_target_clear_dispatch);
harness.run("applies_viewport_dispatch", applies_viewport_dispatch);
harness.run("rejects_incomplete_viewport_dispatch", rejects_incomplete_viewport_dispatch);
harness.run("applies_scissor_dispatch", applies_scissor_dispatch);