Route RTT framebuffer binding through renderer GL

This commit is contained in:
2026-06-03 06:35:47 +02:00
parent 3128a0d309
commit 779d6b0387
6 changed files with 149 additions and 29 deletions

View File

@@ -684,6 +684,36 @@ pp::foundation::Status readback_opengl_framebuffer(
return pp::foundation::Status::success();
}
pp::foundation::Result<OpenGlFramebufferBindingState> bind_opengl_framebuffer_for_draw_read(
std::uint32_t framebuffer,
OpenGlFramebufferBindDispatch dispatch) noexcept
{
if (dispatch.get_integer == nullptr || dispatch.bind_framebuffer == nullptr) {
return pp::foundation::Result<OpenGlFramebufferBindingState>::failure(
pp::foundation::Status::invalid_argument("OpenGL framebuffer bind dispatch callbacks must not be null"));
}
OpenGlFramebufferBindingState binding {};
dispatch.get_integer(draw_framebuffer_binding_query(), &binding.draw_framebuffer);
dispatch.get_integer(read_framebuffer_binding_query(), &binding.read_framebuffer);
dispatch.bind_framebuffer(draw_framebuffer_target(), framebuffer);
dispatch.bind_framebuffer(read_framebuffer_target(), framebuffer);
return pp::foundation::Result<OpenGlFramebufferBindingState>::success(binding);
}
pp::foundation::Status restore_opengl_framebuffer_binding(
OpenGlFramebufferBindingState binding,
OpenGlFramebufferRestoreDispatch dispatch) noexcept
{
if (dispatch.bind_framebuffer == nullptr) {
return pp::foundation::Status::invalid_argument("OpenGL framebuffer restore dispatch callback must not be null");
}
dispatch.bind_framebuffer(draw_framebuffer_target(), static_cast<std::uint32_t>(binding.draw_framebuffer));
dispatch.bind_framebuffer(read_framebuffer_target(), static_cast<std::uint32_t>(binding.read_framebuffer));
return pp::foundation::Status::success();
}
std::uint32_t extension_count_query() noexcept
{
return gl_num_extensions;

View File

@@ -167,6 +167,11 @@ struct OpenGlFramebufferReadback {
void* pixels = nullptr;
};
struct OpenGlFramebufferBindingState {
std::int32_t draw_framebuffer = 0;
std::int32_t read_framebuffer = 0;
};
struct OpenGlWindowsWglContextConfig {
std::array<std::int32_t, 9> context_attributes {};
std::array<std::int32_t, 15> pixel_format_attributes {};
@@ -381,6 +386,15 @@ struct OpenGlFramebufferReadbackDispatch {
OpenGlReadPixelsFn read_pixels = nullptr;
};
struct OpenGlFramebufferBindDispatch {
OpenGlGetIntegerFn get_integer = nullptr;
OpenGlBindFramebufferFn bind_framebuffer = nullptr;
};
struct OpenGlFramebufferRestoreDispatch {
OpenGlBindFramebufferFn bind_framebuffer = nullptr;
};
[[nodiscard]] OpenGlCapabilities detect_opengl_capabilities(
std::span<const std::string_view> extensions,
OpenGlRuntime runtime) noexcept;
@@ -437,6 +451,12 @@ struct OpenGlFramebufferReadbackDispatch {
[[nodiscard]] pp::foundation::Status readback_opengl_framebuffer(
OpenGlFramebufferReadback readback,
OpenGlFramebufferReadbackDispatch dispatch) noexcept;
[[nodiscard]] pp::foundation::Result<OpenGlFramebufferBindingState> bind_opengl_framebuffer_for_draw_read(
std::uint32_t framebuffer,
OpenGlFramebufferBindDispatch dispatch) noexcept;
[[nodiscard]] pp::foundation::Status restore_opengl_framebuffer_binding(
OpenGlFramebufferBindingState binding,
OpenGlFramebufferRestoreDispatch dispatch) noexcept;
[[nodiscard]] std::uint32_t extension_count_query() noexcept;
[[nodiscard]] std::uint32_t extension_string_name() noexcept;

View File

@@ -24,26 +24,6 @@ namespace {
return static_cast<GLenum>(pp::renderer::gl::framebuffer_target());
}
[[nodiscard]] GLenum draw_framebuffer_target() noexcept
{
return static_cast<GLenum>(pp::renderer::gl::draw_framebuffer_target());
}
[[nodiscard]] GLenum read_framebuffer_target() noexcept
{
return static_cast<GLenum>(pp::renderer::gl::read_framebuffer_target());
}
[[nodiscard]] GLenum draw_framebuffer_binding_query() noexcept
{
return static_cast<GLenum>(pp::renderer::gl::draw_framebuffer_binding_query());
}
[[nodiscard]] GLenum read_framebuffer_binding_query() noexcept
{
return static_cast<GLenum>(pp::renderer::gl::read_framebuffer_binding_query());
}
void query_opengl_integer(std::uint32_t name, std::int32_t* value) noexcept
{
glGetIntegerv(static_cast<GLenum>(name), reinterpret_cast<GLint*>(value));
@@ -437,10 +417,19 @@ void RTT::bindFramebuffer()
#endif
}
#endif // _DEBUG
glGetIntegerv(draw_framebuffer_binding_query(), &oldDFboID);
glGetIntegerv(read_framebuffer_binding_query(), &oldRFboID);
glBindFramebuffer(draw_framebuffer_target(), fboID);
glBindFramebuffer(read_framebuffer_target(), fboID);
const auto binding = pp::renderer::gl::bind_opengl_framebuffer_for_draw_read(
static_cast<std::uint32_t>(fboID),
pp::renderer::gl::OpenGlFramebufferBindDispatch {
.get_integer = query_opengl_integer,
.bind_framebuffer = bind_opengl_framebuffer,
});
if (!binding.ok()) {
LOG("RTT::bindFramebuffer() failed because: %s", binding.status().message);
return;
}
oldDFboID = static_cast<GLint>(binding.value().draw_framebuffer);
oldRFboID = static_cast<GLint>(binding.value().read_framebuffer);
bound = true;
}
@@ -449,8 +438,19 @@ void RTT::unbindFramebuffer()
assert(App::I->is_render_thread());
if (!bound)
return;
glBindFramebuffer(draw_framebuffer_target(), oldDFboID);
glBindFramebuffer(read_framebuffer_target(), oldRFboID);
const auto status = pp::renderer::gl::restore_opengl_framebuffer_binding(
pp::renderer::gl::OpenGlFramebufferBindingState {
.draw_framebuffer = oldDFboID,
.read_framebuffer = oldRFboID,
},
pp::renderer::gl::OpenGlFramebufferRestoreDispatch {
.bind_framebuffer = bind_opengl_framebuffer,
});
if (!status.ok()) {
LOG("RTT::unbindFramebuffer() failed because: %s", status.message);
return;
}
oldRFboID = 0;
oldDFboID = 0;
bound = false;