aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <[email protected]>2025-04-08 14:10:35 +0200
committerLaszlo Agocs <[email protected]>2025-05-02 23:21:45 +0000
commit30d2b91fb48c2a28188f75d3e87311a2a6aba5d8 (patch)
tree4d08f1e95fbaa054004ae30a16fbf22945d0deba /src
parent01b315661000469ed6a95324fd7f55f630eb3621 (diff)
Reuse depth-stencil buffer between layers like Qt 5 didHEADdev
Port QSGDepthStencilBuffer in a slightly changed form from Qt 5. Two layers in the same scene can use the same single depth-stencil buffer, instead of creating a dedicated one for each. As long as the size and sample count is the same. The render passes are recorded sequentially, and there is no need for the depth-stencil content once a render pass is done. The catch is having to deal with changing sizes, e.g. a window resize often leads to changed sizes for the layers of the scene. We do not want to end up cached renderbuffer objects with sizes that will possibly never be needed again. The Qt 5 approach solves this with reference counting and QShared/WeakPointers. Continue with that approach. If there is actually a depth-stencil buffer that is fully physically backed, that is a different question. With Vulkan for instance, on some GPU architectures we expect that the depth-stencil images will be transient + lazily allocated + no store, so it may matter little how many images we have. Similar things might happen in GLES implementations on tiled GPU architectures. However, generally it is ideal if the Qt 5 behavior is kept, so that no confusion arises from an extra renderbuffer or two showing up when counting and comparing resources in frame captures between Qt 5 and 6. Fixes: QTBUG-135813 Pick-to: 6.9 6.8 Change-Id: I238dc53600f4a00e6ee2f7ccc97ac33ff189e3c5 Reviewed-by: Andy Nichols <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp46
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h18
-rw-r--r--src/quick/scenegraph/qsgrhilayer.cpp22
-rw-r--r--src/quick/scenegraph/qsgrhilayer_p.h3
4 files changed, 75 insertions, 14 deletions
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 1b0753e9ae..6b0a8d6556 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -101,6 +101,14 @@ void QSGDefaultRenderContext::invalidate()
qDeleteAll(m_textures);
m_textures.clear();
+ for (auto it = m_depthStencilBuffers.cbegin(), end = m_depthStencilBuffers.cend(); it != end; ++it) {
+ QSharedPointer<QSGDepthStencilBuffer> buf = it.value().toStrongRef();
+ delete buf->ds;
+ buf->ds = nullptr;
+ buf->rc = nullptr;
+ }
+ m_depthStencilBuffers.clear();
+
/* The cleanup of the atlas textures is a bit intriguing.
As part of the cleanup in the threaded render loop, we
do:
@@ -296,6 +304,44 @@ void QSGDefaultRenderContext::resetGlyphCacheResources()
m_pendingGlyphCacheTextures.clear();
}
+QSGDepthStencilBuffer::~QSGDepthStencilBuffer()
+{
+ if (rc && ds) {
+ const auto key = std::pair(ds->pixelSize(), ds->sampleCount());
+ rc->m_depthStencilBuffers.remove(key);
+ }
+ delete ds;
+}
+
+QSharedPointer<QSGDepthStencilBuffer> QSGDefaultRenderContext::getDepthStencilBuffer(const QSize &size, int sampleCount)
+{
+ const auto key = std::pair(size, sampleCount);
+ auto it = m_depthStencilBuffers.constFind(key);
+ if (it != m_depthStencilBuffers.cend()) {
+ if (it.value())
+ return it.value().toStrongRef();
+ }
+
+ QRhiRenderBuffer *ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, size, sampleCount);
+ if (!ds->create()) {
+ qWarning("Failed to build depth-stencil buffer for layer");
+ delete ds;
+ return {};
+ }
+ QSharedPointer<QSGDepthStencilBuffer> buf(new QSGDepthStencilBuffer(ds));
+ addDepthStencilBuffer(buf);
+ return buf;
+}
+
+void QSGDefaultRenderContext::addDepthStencilBuffer(const QSharedPointer<QSGDepthStencilBuffer> &ds)
+{
+ if (ds) {
+ const auto key = std::pair(ds->ds->pixelSize(), ds->ds->sampleCount());
+ ds->rc = this;
+ m_depthStencilBuffers.insert(key, ds.toWeakRef());
+ }
+}
+
QT_END_NAMESPACE
#include "moc_qsgdefaultrendercontext_p.cpp"
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index c3352aa89f..be3d1c1312 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -25,13 +25,25 @@ class QRhiCommandBuffer;
class QRhiRenderPassDescriptor;
class QRhiResourceUpdateBatch;
class QRhiTexture;
+class QRhiRenderBuffer;
class QSGMaterialShader;
class QSurface;
+class QSGDefaultRenderContext;
namespace QSGRhiAtlasTexture {
class Manager;
}
+class QSGDepthStencilBuffer
+{
+public:
+ QSGDepthStencilBuffer() { }
+ QSGDepthStencilBuffer(QRhiRenderBuffer *ds) : ds(ds) { }
+ ~QSGDepthStencilBuffer();
+ QRhiRenderBuffer *ds = nullptr;
+ QSGDefaultRenderContext *rc = nullptr;
+};
+
class Q_QUICK_EXPORT QSGDefaultRenderContext : public QSGRenderContext
{
Q_OBJECT
@@ -107,6 +119,9 @@ public:
void deferredReleaseGlyphCacheTexture(QRhiTexture *texture);
void resetGlyphCacheResources();
+ QSharedPointer<QSGDepthStencilBuffer> getDepthStencilBuffer(const QSize &size, int sampleCount);
+ void addDepthStencilBuffer(const QSharedPointer<QSGDepthStencilBuffer> &ds);
+
protected:
InitParams m_initParams;
QRhi *m_rhi;
@@ -119,6 +134,9 @@ protected:
QRhiResourceUpdateBatch *m_glyphCacheResourceUpdates;
QSet<QRhiTexture *> m_pendingGlyphCacheTextures;
QHash<FontKey, QSGCurveGlyphAtlas *> m_curveGlyphAtlases;
+ QHash<std::pair<QSize, int>, QWeakPointer<QSGDepthStencilBuffer>> m_depthStencilBuffers;
+
+ friend class QSGDepthStencilBuffer;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgrhilayer.cpp b/src/quick/scenegraph/qsgrhilayer.cpp
index 3ce7e5e81a..e802805d0d 100644
--- a/src/quick/scenegraph/qsgrhilayer.cpp
+++ b/src/quick/scenegraph/qsgrhilayer.cpp
@@ -5,7 +5,6 @@
#include <private/qqmlglobal_p.h>
#include <private/qsgrenderer_p.h>
-#include <private/qsgdefaultrendercontext_p.h>
QSGRhiLayer::QSGRhiLayer(QSGRenderContext *context)
: QSGLayer(*(new QSGTexturePrivate(this)))
@@ -210,8 +209,7 @@ void QSGRhiLayer::releaseResources()
delete m_rtRp;
m_rtRp = nullptr;
- delete m_ds;
- m_ds = nullptr;
+ m_ds.clear();
delete m_msaaColorBuffer;
m_msaaColorBuffer = nullptr;
@@ -278,9 +276,8 @@ void QSGRhiLayer::grab()
return;
}
if (depthBufferEnabled) {
- m_ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, m_pixelSize, effectiveSamples);
- if (!m_ds->create()) {
- qWarning("Failed to build depth-stencil buffer for layer");
+ m_ds = m_context->getDepthStencilBuffer(m_pixelSize, effectiveSamples);
+ if (!m_ds) {
releaseResources();
return;
}
@@ -290,7 +287,7 @@ void QSGRhiLayer::grab()
color0.setResolveTexture(m_texture);
desc.setColorAttachments({ color0 });
if (depthBufferEnabled)
- desc.setDepthStencilBuffer(m_ds);
+ desc.setDepthStencilBuffer(m_ds->ds);
m_rt = m_rhi->newTextureRenderTarget(desc);
m_rtRp = m_rt->newCompatibleRenderPassDescriptor();
if (!m_rtRp) {
@@ -313,9 +310,8 @@ void QSGRhiLayer::grab()
return;
}
if (depthBufferEnabled) {
- m_ds = m_rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, m_pixelSize);
- if (!m_ds->create()) {
- qWarning("Failed to build depth-stencil buffer for layer");
+ m_ds = m_context->getDepthStencilBuffer(m_pixelSize, 1);
+ if (!m_ds) {
releaseResources();
return;
}
@@ -332,10 +328,10 @@ void QSGRhiLayer::grab()
}
color0.setTexture(m_secondaryTexture);
}
+ QRhiTextureRenderTargetDescription desc({ color0 });
if (depthBufferEnabled)
- m_rt = m_rhi->newTextureRenderTarget({ color0, m_ds });
- else
- m_rt = m_rhi->newTextureRenderTarget({ color0 });
+ desc.setDepthStencilBuffer(m_ds->ds);
+ m_rt = m_rhi->newTextureRenderTarget(desc);
m_rtRp = m_rt->newCompatibleRenderPassDescriptor();
if (!m_rtRp) {
qWarning("Failed to build render pass descriptor for layer");
diff --git a/src/quick/scenegraph/qsgrhilayer_p.h b/src/quick/scenegraph/qsgrhilayer_p.h
index 922192ec5e..d6d9165123 100644
--- a/src/quick/scenegraph/qsgrhilayer_p.h
+++ b/src/quick/scenegraph/qsgrhilayer_p.h
@@ -17,6 +17,7 @@
#include <private/qsgadaptationlayer_p.h>
#include <private/qsgcontext_p.h>
#include <private/qsgtexture_p.h>
+#include <private/qsgdefaultrendercontext_p.h>
#include <rhi/qrhi.h>
QT_BEGIN_NAMESPACE
@@ -73,7 +74,7 @@ private:
QSGRenderer *m_renderer = nullptr;
QRhiTexture *m_texture = nullptr;
- QRhiRenderBuffer *m_ds = nullptr;
+ QSharedPointer<QSGDepthStencilBuffer> m_ds;
QRhiRenderBuffer *m_msaaColorBuffer = nullptr;
QRhiTexture *m_secondaryTexture = nullptr;
QRhiTextureRenderTarget *m_rt = nullptr;