summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2024-03-13 16:41:19 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2024-03-14 15:54:53 +0100
commit0c85b69b860f4222bf0850f2cf5970312b45bfea (patch)
tree565592b780777f53a50c35c8e83daee84cffad01 /src/gui
parent1b374fc4c1d381c85aef0bb772951c282a0c47be (diff)
rhi: gl: Further enhance depth-stencil support for QRhiTextureRenderTarget
...in particular when doing multisampling with multiview. With this the results are now identical with multiview and multiview+MSAA on the Quest 3. (previously the depth buffer was clearly broken when doing multiview+MSAA) Change-Id: Iec3c6af66510ab76cb0591eb8d002aa5855a399e Reviewed-by: Andy Nichols <andy.nichols@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/rhi/qrhigles2.cpp76
-rw-r--r--src/gui/rhi/qrhigles2_p.h2
2 files changed, 67 insertions, 11 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 8e98bcd736..d86b5368c4 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -1153,6 +1153,7 @@ void QRhiGles2::executeDeferredReleases()
break;
case QRhiGles2::DeferredReleaseEntry::TextureRenderTarget:
f->glDeleteFramebuffers(1, &e.textureRenderTarget.framebuffer);
+ f->glDeleteTextures(1, &e.textureRenderTarget.nonMsaaThrowawayDepthTexture);
break;
default:
Q_UNREACHABLE();
@@ -5775,8 +5776,10 @@ void QGles2TextureRenderTarget::destroy()
e.type = QRhiGles2::DeferredReleaseEntry::TextureRenderTarget;
e.textureRenderTarget.framebuffer = framebuffer;
+ e.textureRenderTarget.nonMsaaThrowawayDepthTexture = nonMsaaThrowawayDepthTexture;
framebuffer = 0;
+ nonMsaaThrowawayDepthTexture = 0;
QRHI_RES_RHI(QRhiGles2);
if (rhiD) {
@@ -5904,12 +5907,14 @@ bool QGles2TextureRenderTarget::create()
} else {
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
depthRbD->renderbuffer);
- if (depthRbD->stencilRenderbuffer)
+ if (depthRbD->stencilRenderbuffer) {
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
depthRbD->stencilRenderbuffer);
- else // packed
+ } else {
+ // packed depth-stencil
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
depthRbD->renderbuffer);
+ }
}
if (d.colorAttCount == 0) {
d.pixelSize = depthRbD->pixelSize();
@@ -5920,17 +5925,66 @@ bool QGles2TextureRenderTarget::create()
if (multiViewCount < 2) {
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexD->target,
depthTexD->texture, 0);
- } else {
- // This path is OpenGL (ES) 3.0+ and specific to multiview, so
- // needsDepthStencilCombinedAttach is not a thing. The depth
- // texture here must be an array with at least multiViewCount
- // elements, and the format should be D24 or D32F for depth
- // only, or D24S8 for depth and stencil.
- rhiD->glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexD->texture,
- 0, 0, multiViewCount);
if (rhiD->isStencilSupportingFormat(depthTexD->format())) {
- rhiD->glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthTexD->texture,
+ rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthTexD->target,
+ depthTexD->texture, 0);
+ }
+ } else {
+ if (depthTexD->sampleCount() > 1 && rhiD->caps.glesMultiviewMultisampleRenderToTexture) {
+ // And so it turns out
+ // https://registry.khronos.org/OpenGL/extensions/OVR/OVR_multiview.txt
+ // does not work with multisample 2D texture arrays. (at least
+ // that's what Issue 30 in the extension spec seems to imply)
+ //
+ // There is https://registry.khronos.org/OpenGL/extensions/EXT/EXT_multiview_texture_multisample.txt
+ // that seems to resolve that, but that does not seem to
+ // work (or not available) on GLES devices such as the Quest 3.
+ //
+ // So instead, on GLES we can use the
+ // multisample-multiview-auto-resolving version (which in
+ // turn is not supported on desktop GL e.g. by NVIDIA), too
+ // bad we have a multisample depth texture array here as
+ // every other API out there requires that. So create a
+ // temporary one ignoring what the user has already created.
+ //
+ // (also, why on Earth would we want to waste time on
+ // resolving the throwaway depth-stencil buffer? Hopefully
+ // the invalidation at the end of the pass avoids that...)
+ if (!m_flags.testFlag(DoNotStoreDepthStencilContents)) {
+ qWarning("Attempted to create a multiview+multisample QRhiTextureRenderTarget, but DoNotStoreDepthStencilContents was not set."
+ " This path has no choice but to behave as if DoNotStoreDepthStencilContents was set, because QRhi is forced to create"
+ " a throwaway non-multisample depth texture here. Set the flag to silence this warning.");
+ }
+ if (!nonMsaaThrowawayDepthTexture) {
+ rhiD->f->glGenTextures(1, &nonMsaaThrowawayDepthTexture);
+ rhiD->f->glBindTexture(GL_TEXTURE_2D_ARRAY, nonMsaaThrowawayDepthTexture);
+ rhiD->f->glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH24_STENCIL8,
+ depthTexD->pixelSize().width(), depthTexD->pixelSize().height(), multiViewCount);
+ }
+ rhiD->glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ nonMsaaThrowawayDepthTexture,
+ 0,
+ depthTexD->sampleCount(),
+ 0,
+ multiViewCount);
+ rhiD->glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ nonMsaaThrowawayDepthTexture,
+ 0,
+ depthTexD->sampleCount(),
+ 0,
+ multiViewCount);
+ } else {
+ // The depth texture here must be an array with at least
+ // multiViewCount elements, and the format should be D24 or D32F
+ // for depth only, or D24S8 for depth and stencil.
+ rhiD->glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexD->texture,
0, 0, multiViewCount);
+ if (rhiD->isStencilSupportingFormat(depthTexD->format())) {
+ rhiD->glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthTexD->texture,
+ 0, 0, multiViewCount);
+ }
}
}
if (d.colorAttCount == 0) {
diff --git a/src/gui/rhi/qrhigles2_p.h b/src/gui/rhi/qrhigles2_p.h
index 04ef596267..1365d439c2 100644
--- a/src/gui/rhi/qrhigles2_p.h
+++ b/src/gui/rhi/qrhigles2_p.h
@@ -215,6 +215,7 @@ struct QGles2TextureRenderTarget : public QRhiTextureRenderTarget
QGles2RenderTargetData d;
GLuint framebuffer = 0;
+ GLuint nonMsaaThrowawayDepthTexture = 0;
friend class QRhiGles2;
};
@@ -1103,6 +1104,7 @@ public:
} renderbuffer;
struct {
GLuint framebuffer;
+ GLuint nonMsaaThrowawayDepthTexture;
} textureRenderTarget;
};
};