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>
This commit is contained in:
parent
1b374fc4c1
commit
0c85b69b86
@ -1153,6 +1153,7 @@ void QRhiGles2::executeDeferredReleases()
|
|||||||
break;
|
break;
|
||||||
case QRhiGles2::DeferredReleaseEntry::TextureRenderTarget:
|
case QRhiGles2::DeferredReleaseEntry::TextureRenderTarget:
|
||||||
f->glDeleteFramebuffers(1, &e.textureRenderTarget.framebuffer);
|
f->glDeleteFramebuffers(1, &e.textureRenderTarget.framebuffer);
|
||||||
|
f->glDeleteTextures(1, &e.textureRenderTarget.nonMsaaThrowawayDepthTexture);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Q_UNREACHABLE();
|
Q_UNREACHABLE();
|
||||||
@ -5775,8 +5776,10 @@ void QGles2TextureRenderTarget::destroy()
|
|||||||
e.type = QRhiGles2::DeferredReleaseEntry::TextureRenderTarget;
|
e.type = QRhiGles2::DeferredReleaseEntry::TextureRenderTarget;
|
||||||
|
|
||||||
e.textureRenderTarget.framebuffer = framebuffer;
|
e.textureRenderTarget.framebuffer = framebuffer;
|
||||||
|
e.textureRenderTarget.nonMsaaThrowawayDepthTexture = nonMsaaThrowawayDepthTexture;
|
||||||
|
|
||||||
framebuffer = 0;
|
framebuffer = 0;
|
||||||
|
nonMsaaThrowawayDepthTexture = 0;
|
||||||
|
|
||||||
QRHI_RES_RHI(QRhiGles2);
|
QRHI_RES_RHI(QRhiGles2);
|
||||||
if (rhiD) {
|
if (rhiD) {
|
||||||
@ -5904,12 +5907,14 @@ bool QGles2TextureRenderTarget::create()
|
|||||||
} else {
|
} else {
|
||||||
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
||||||
depthRbD->renderbuffer);
|
depthRbD->renderbuffer);
|
||||||
if (depthRbD->stencilRenderbuffer)
|
if (depthRbD->stencilRenderbuffer) {
|
||||||
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||||
depthRbD->stencilRenderbuffer);
|
depthRbD->stencilRenderbuffer);
|
||||||
else // packed
|
} else {
|
||||||
|
// packed depth-stencil
|
||||||
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
rhiD->f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||||
depthRbD->renderbuffer);
|
depthRbD->renderbuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (d.colorAttCount == 0) {
|
if (d.colorAttCount == 0) {
|
||||||
d.pixelSize = depthRbD->pixelSize();
|
d.pixelSize = depthRbD->pixelSize();
|
||||||
@ -5920,17 +5925,66 @@ bool QGles2TextureRenderTarget::create()
|
|||||||
if (multiViewCount < 2) {
|
if (multiViewCount < 2) {
|
||||||
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexD->target,
|
rhiD->f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexD->target,
|
||||||
depthTexD->texture, 0);
|
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())) {
|
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);
|
0, 0, multiViewCount);
|
||||||
|
if (rhiD->isStencilSupportingFormat(depthTexD->format())) {
|
||||||
|
rhiD->glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthTexD->texture,
|
||||||
|
0, 0, multiViewCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (d.colorAttCount == 0) {
|
if (d.colorAttCount == 0) {
|
||||||
|
@ -215,6 +215,7 @@ struct QGles2TextureRenderTarget : public QRhiTextureRenderTarget
|
|||||||
|
|
||||||
QGles2RenderTargetData d;
|
QGles2RenderTargetData d;
|
||||||
GLuint framebuffer = 0;
|
GLuint framebuffer = 0;
|
||||||
|
GLuint nonMsaaThrowawayDepthTexture = 0;
|
||||||
friend class QRhiGles2;
|
friend class QRhiGles2;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1103,6 +1104,7 @@ public:
|
|||||||
} renderbuffer;
|
} renderbuffer;
|
||||||
struct {
|
struct {
|
||||||
GLuint framebuffer;
|
GLuint framebuffer;
|
||||||
|
GLuint nonMsaaThrowawayDepthTexture;
|
||||||
} textureRenderTarget;
|
} textureRenderTarget;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user