Route RTT blit readback through renderer GL
This commit is contained in:
@@ -71,6 +71,19 @@ struct RecordedOpenGlReadPixelsCall {
|
||||
void* pixels = nullptr;
|
||||
};
|
||||
|
||||
struct RecordedOpenGlBlitFramebufferCall {
|
||||
std::int32_t source_x0 = 0;
|
||||
std::int32_t source_y0 = 0;
|
||||
std::int32_t source_x1 = 0;
|
||||
std::int32_t source_y1 = 0;
|
||||
std::int32_t destination_x0 = 0;
|
||||
std::int32_t destination_y0 = 0;
|
||||
std::int32_t destination_x1 = 0;
|
||||
std::int32_t destination_y1 = 0;
|
||||
std::uint32_t mask = 0;
|
||||
std::uint32_t filter = 0;
|
||||
};
|
||||
|
||||
std::vector<RecordedOpenGlStateCall> recorded_state_calls;
|
||||
std::vector<std::uint32_t> recorded_string_queries;
|
||||
std::vector<pp::renderer::gl::OpenGlDefaultClear> recorded_clear_calls;
|
||||
@@ -89,6 +102,7 @@ std::vector<std::uint32_t> recorded_deleted_framebuffers;
|
||||
std::vector<RecordedOpenGlFramebufferAttachmentCall> recorded_framebuffer_attachment_calls;
|
||||
std::vector<std::uint32_t> recorded_framebuffer_status_queries;
|
||||
std::vector<RecordedOpenGlReadPixelsCall> recorded_read_pixels_calls;
|
||||
std::vector<RecordedOpenGlBlitFramebufferCall> recorded_blit_framebuffer_calls;
|
||||
std::uint32_t next_texture_id = 91U;
|
||||
std::uint32_t next_framebuffer_id = 44U;
|
||||
std::uint32_t configured_framebuffer_status = 0x8CD5U;
|
||||
@@ -407,6 +421,32 @@ void record_read_pixels(
|
||||
});
|
||||
}
|
||||
|
||||
void record_blit_framebuffer(
|
||||
std::int32_t source_x0,
|
||||
std::int32_t source_y0,
|
||||
std::int32_t source_x1,
|
||||
std::int32_t source_y1,
|
||||
std::int32_t destination_x0,
|
||||
std::int32_t destination_y0,
|
||||
std::int32_t destination_x1,
|
||||
std::int32_t destination_y1,
|
||||
std::uint32_t mask,
|
||||
std::uint32_t filter) noexcept
|
||||
{
|
||||
recorded_blit_framebuffer_calls.push_back(RecordedOpenGlBlitFramebufferCall {
|
||||
.source_x0 = source_x0,
|
||||
.source_y0 = source_y0,
|
||||
.source_x1 = source_x1,
|
||||
.source_y1 = source_y1,
|
||||
.destination_x0 = destination_x0,
|
||||
.destination_y0 = destination_y0,
|
||||
.destination_x1 = destination_x1,
|
||||
.destination_y1 = destination_y1,
|
||||
.mask = mask,
|
||||
.filter = filter,
|
||||
});
|
||||
}
|
||||
|
||||
void detects_common_extension_capabilities(pp::tests::Harness& h)
|
||||
{
|
||||
constexpr std::array<std::string_view, 2> extensions {
|
||||
@@ -1743,6 +1783,162 @@ void rejects_incomplete_texture_2d_readback_dispatch(pp::tests::Harness& h)
|
||||
PP_EXPECT(h, result.status().code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void blits_framebuffers_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_integer_queries.clear();
|
||||
recorded_binding_calls.clear();
|
||||
recorded_blit_framebuffer_calls.clear();
|
||||
|
||||
const auto status = pp::renderer::gl::blit_opengl_framebuffer(
|
||||
pp::renderer::gl::OpenGlFramebufferBlit {
|
||||
.source_framebuffer = 13U,
|
||||
.destination_framebuffer = 17U,
|
||||
.source_rect = pp::renderer::gl::OpenGlFramebufferRect {
|
||||
.x0 = 1,
|
||||
.y0 = 2,
|
||||
.x1 = 65,
|
||||
.y1 = 34,
|
||||
},
|
||||
.destination_rect = pp::renderer::gl::OpenGlFramebufferRect {
|
||||
.x0 = 3,
|
||||
.y0 = 4,
|
||||
.x1 = 131,
|
||||
.y1 = 68,
|
||||
},
|
||||
.mask = 0x00004000U,
|
||||
.filter = 0x2601U,
|
||||
},
|
||||
pp::renderer::gl::OpenGlFramebufferBlitDispatch {
|
||||
.get_integer = record_get_integer,
|
||||
.bind_framebuffer = record_bind_framebuffer,
|
||||
.blit_framebuffer = record_blit_framebuffer,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, status.ok());
|
||||
PP_EXPECT(h, recorded_integer_queries.size() == 2U);
|
||||
PP_EXPECT(h, recorded_integer_queries[0] == 0x8CA6U);
|
||||
PP_EXPECT(h, recorded_integer_queries[1] == 0x8CAAU);
|
||||
PP_EXPECT(h, recorded_binding_calls.size() == 4U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].kind == RecordedOpenGlBindingCall::Kind::bind_framebuffer);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].first == 0x8CA9U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].second == 17U);
|
||||
PP_EXPECT(h, recorded_binding_calls[1].first == 0x8CA8U);
|
||||
PP_EXPECT(h, recorded_binding_calls[1].second == 13U);
|
||||
PP_EXPECT(h, recorded_binding_calls[2].first == 0x8CA9U);
|
||||
PP_EXPECT(h, recorded_binding_calls[2].second == 7U);
|
||||
PP_EXPECT(h, recorded_binding_calls[3].first == 0x8CA8U);
|
||||
PP_EXPECT(h, recorded_binding_calls[3].second == 9U);
|
||||
PP_EXPECT(h, recorded_blit_framebuffer_calls.size() == 1U);
|
||||
PP_EXPECT(h, recorded_blit_framebuffer_calls[0].source_x0 == 1);
|
||||
PP_EXPECT(h, recorded_blit_framebuffer_calls[0].source_y1 == 34);
|
||||
PP_EXPECT(h, recorded_blit_framebuffer_calls[0].destination_x1 == 131);
|
||||
PP_EXPECT(h, recorded_blit_framebuffer_calls[0].mask == 0x00004000U);
|
||||
PP_EXPECT(h, recorded_blit_framebuffer_calls[0].filter == 0x2601U);
|
||||
}
|
||||
|
||||
void rejects_invalid_framebuffer_blits(pp::tests::Harness& h)
|
||||
{
|
||||
const auto missing_dispatch = pp::renderer::gl::blit_opengl_framebuffer(
|
||||
pp::renderer::gl::OpenGlFramebufferBlit {
|
||||
.source_rect = pp::renderer::gl::OpenGlFramebufferRect { .x1 = 1, .y1 = 1 },
|
||||
.destination_rect = pp::renderer::gl::OpenGlFramebufferRect { .x1 = 1, .y1 = 1 },
|
||||
.mask = 0x00004000U,
|
||||
.filter = 0x2601U,
|
||||
},
|
||||
pp::renderer::gl::OpenGlFramebufferBlitDispatch {
|
||||
.get_integer = record_get_integer,
|
||||
.bind_framebuffer = record_bind_framebuffer,
|
||||
});
|
||||
const auto empty_source = pp::renderer::gl::blit_opengl_framebuffer(
|
||||
pp::renderer::gl::OpenGlFramebufferBlit {
|
||||
.source_rect = pp::renderer::gl::OpenGlFramebufferRect { .x1 = 0, .y1 = 1 },
|
||||
.destination_rect = pp::renderer::gl::OpenGlFramebufferRect { .x1 = 1, .y1 = 1 },
|
||||
.mask = 0x00004000U,
|
||||
.filter = 0x2601U,
|
||||
},
|
||||
pp::renderer::gl::OpenGlFramebufferBlitDispatch {
|
||||
.get_integer = record_get_integer,
|
||||
.bind_framebuffer = record_bind_framebuffer,
|
||||
.blit_framebuffer = record_blit_framebuffer,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, !missing_dispatch.ok());
|
||||
PP_EXPECT(h, missing_dispatch.code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !empty_source.ok());
|
||||
PP_EXPECT(h, empty_source.code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void reads_back_framebuffer_through_dispatch(pp::tests::Harness& h)
|
||||
{
|
||||
recorded_integer_queries.clear();
|
||||
recorded_binding_calls.clear();
|
||||
recorded_read_pixels_calls.clear();
|
||||
std::array<std::uint8_t, 16> pixels {};
|
||||
|
||||
const auto status = pp::renderer::gl::readback_opengl_framebuffer(
|
||||
pp::renderer::gl::OpenGlFramebufferReadback {
|
||||
.framebuffer = 23U,
|
||||
.x = 2,
|
||||
.y = 3,
|
||||
.width = 4,
|
||||
.height = 5,
|
||||
.format = pp::renderer::gl::rgba8_readback_format(),
|
||||
.pixels = pixels.data(),
|
||||
},
|
||||
pp::renderer::gl::OpenGlFramebufferReadbackDispatch {
|
||||
.get_integer = record_get_integer,
|
||||
.bind_framebuffer = record_bind_framebuffer,
|
||||
.read_pixels = record_read_pixels,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, status.ok());
|
||||
PP_EXPECT(h, recorded_integer_queries.size() == 1U);
|
||||
PP_EXPECT(h, recorded_integer_queries[0] == 0x8CAAU);
|
||||
PP_EXPECT(h, recorded_binding_calls.size() == 2U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].first == 0x8CA8U);
|
||||
PP_EXPECT(h, recorded_binding_calls[0].second == 23U);
|
||||
PP_EXPECT(h, recorded_binding_calls[1].first == 0x8CA8U);
|
||||
PP_EXPECT(h, recorded_binding_calls[1].second == 9U);
|
||||
PP_EXPECT(h, recorded_read_pixels_calls.size() == 1U);
|
||||
PP_EXPECT(h, recorded_read_pixels_calls[0].x == 2);
|
||||
PP_EXPECT(h, recorded_read_pixels_calls[0].y == 3);
|
||||
PP_EXPECT(h, recorded_read_pixels_calls[0].width == 4);
|
||||
PP_EXPECT(h, recorded_read_pixels_calls[0].height == 5);
|
||||
PP_EXPECT(h, recorded_read_pixels_calls[0].pixels == pixels.data());
|
||||
}
|
||||
|
||||
void rejects_invalid_framebuffer_readbacks(pp::tests::Harness& h)
|
||||
{
|
||||
std::array<std::uint8_t, 4> pixels {};
|
||||
const auto missing_dispatch = pp::renderer::gl::readback_opengl_framebuffer(
|
||||
pp::renderer::gl::OpenGlFramebufferReadback {
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.format = pp::renderer::gl::rgba8_readback_format(),
|
||||
.pixels = pixels.data(),
|
||||
},
|
||||
pp::renderer::gl::OpenGlFramebufferReadbackDispatch {
|
||||
.get_integer = record_get_integer,
|
||||
.bind_framebuffer = record_bind_framebuffer,
|
||||
});
|
||||
const auto missing_pixels = pp::renderer::gl::readback_opengl_framebuffer(
|
||||
pp::renderer::gl::OpenGlFramebufferReadback {
|
||||
.width = 1,
|
||||
.height = 1,
|
||||
.format = pp::renderer::gl::rgba8_readback_format(),
|
||||
},
|
||||
pp::renderer::gl::OpenGlFramebufferReadbackDispatch {
|
||||
.get_integer = record_get_integer,
|
||||
.bind_framebuffer = record_bind_framebuffer,
|
||||
.read_pixels = record_read_pixels,
|
||||
});
|
||||
|
||||
PP_EXPECT(h, !missing_dispatch.ok());
|
||||
PP_EXPECT(h, missing_dispatch.code == pp::foundation::StatusCode::invalid_argument);
|
||||
PP_EXPECT(h, !missing_pixels.ok());
|
||||
PP_EXPECT(h, missing_pixels.code == pp::foundation::StatusCode::invalid_argument);
|
||||
}
|
||||
|
||||
void maps_renderer_viewports_and_scissors(pp::tests::Harness& h)
|
||||
{
|
||||
const auto viewport = pp::renderer::gl::viewport_for_renderer_viewport(
|
||||
@@ -2145,6 +2341,10 @@ int main()
|
||||
harness.run("reads_back_texture_2d_through_framebuffer_dispatch", reads_back_texture_2d_through_framebuffer_dispatch);
|
||||
harness.run("reports_incomplete_texture_2d_readback_framebuffer", reports_incomplete_texture_2d_readback_framebuffer);
|
||||
harness.run("rejects_incomplete_texture_2d_readback_dispatch", rejects_incomplete_texture_2d_readback_dispatch);
|
||||
harness.run("blits_framebuffers_through_dispatch", blits_framebuffers_through_dispatch);
|
||||
harness.run("rejects_invalid_framebuffer_blits", rejects_invalid_framebuffer_blits);
|
||||
harness.run("reads_back_framebuffer_through_dispatch", reads_back_framebuffer_through_dispatch);
|
||||
harness.run("rejects_invalid_framebuffer_readbacks", rejects_invalid_framebuffer_readbacks);
|
||||
harness.run("maps_renderer_viewports_and_scissors", maps_renderer_viewports_and_scissors);
|
||||
harness.run("maps_renderer_blend_state_tokens", maps_renderer_blend_state_tokens);
|
||||
harness.run("maps_renderer_color_write_masks", maps_renderer_color_write_masks);
|
||||
|
||||
Reference in New Issue
Block a user