From 33d74f3f580213e33cebc11954352887010e1470 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 23 Jan 2025 13:15:54 +0100 Subject: [PATCH] rhi: gl: Honor deafultFbo from the QOpenGLContext better The legacy infrastructure does not map very well to the modern one: it turns out that, somewhat counterintuitively, targeting a QRhiSwapChain for a QWindow may still mean rendering into a texture, when using OpenGL on certain platforms. For example, the Wayland platform plugin implements client-side decorations by binding an FBO upon making a context current on a surface for a (decorated) window, and it also makes defaultFramebufferObject() on the context return the FBO id. The expectation is that this is why errors such as GL_INVALID_OPERATION are encountered in glDrawBuffers on Linux. The QRhi GL backend's assumption that the QRhiRenderTarget being a QRhiResource::SwapChainRenderTarget implies that the target really is the color buffer(s) of a window surface is not in practice sufficient on these platforms. The bound FBO was already correct always (whatever defaultFbo reports), but the code path hit was the wrong one. And there is different code for MRT support (textures only) and stereo rendering (window surface only). Make sure defaultFbo() is queried before taking the decision which path to hit. Pick-to: 6.8 Fixes: QTBUG-122819 Fixes: QTBUG-132780 Change-Id: Iaaab57b031f430178ee4611a4f7a02c854010441 Reviewed-by: Andy Nichols (cherry picked from commit 3869106cc5914fb4a8eda30ae1bd5f68dcee2fda) Reviewed-by: Qt Cherry-pick Bot --- src/gui/rhi/qrhigles2.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index b28cde4477e..2791ba924f9 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -3419,8 +3419,11 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) case QGles2CommandBuffer::Command::BindFramebuffer: { QVarLengthArray bufs; - if (cmd.args.bindFramebuffer.fbo) { - f->glBindFramebuffer(GL_FRAMEBUFFER, cmd.args.bindFramebuffer.fbo); + GLuint fbo = cmd.args.bindFramebuffer.fbo; + if (!fbo) + fbo = ctx->defaultFramebufferObject(); + f->glBindFramebuffer(GL_FRAMEBUFFER, fbo); + if (fbo) { const int colorAttCount = cmd.args.bindFramebuffer.colorAttCount; bufs.append(colorAttCount > 0 ? GL_COLOR_ATTACHMENT0 : GL_NONE); if (caps.maxDrawBuffers > 1) { @@ -3428,7 +3431,6 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb) bufs.append(GL_COLOR_ATTACHMENT0 + uint(i)); } } else { - f->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject()); if (cmd.args.bindFramebuffer.stereo && cmd.args.bindFramebuffer.stereoTarget == QRhiSwapChain::RightBuffer) bufs.append(GL_BACK_RIGHT); else