diff options
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 21 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p_p.h | 17 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d11.cpp | 24 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d12.cpp | 39 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 32 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 40 | ||||
-rw-r--r-- | src/gui/rhi/qrhinull.cpp | 40 | ||||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/tst_qrhi.cpp | 26 |
8 files changed, 192 insertions, 47 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index c5fb6afd7c..41b18e643e 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -2119,11 +2119,17 @@ QRhiResource::~QRhiResource() requirement of not altering QRhiResource objects that are referenced by the frame being recorded. + If the QRhi that created this object is already destroyed, the object is + deleted immediately. + \sa destroy() */ void QRhiResource::deleteLater() { - m_rhi->addDeleteLater(this); + if (m_rhi) + m_rhi->addDeleteLater(this); + else + delete this; } /*! @@ -2172,10 +2178,13 @@ quint64 QRhiResource::globalResourceId() const /*! \return the QRhi that created this resource. + + If the QRhi that created this object is already destroyed, the result is + \nullptr. */ QRhi *QRhiResource::rhi() const { - return m_rhi->q; + return m_rhi ? m_rhi->q : nullptr; } /*! @@ -5100,7 +5109,7 @@ QRhiResource::Type QRhiCommandBuffer::resourceType() const return CommandBuffer; } -static const char *resourceTypeStr(QRhiResource *res) +static const char *resourceTypeStr(const QRhiResource *res) { switch (res->resourceType()) { case QRhiResource::Buffer: @@ -5151,8 +5160,10 @@ QRhiImplementation::~QRhiImplementation() qWarning("QRhi %p going down with %d unreleased resources that own native graphics objects. This is not nice.", q, int(resources.size())); } - for (QRhiResource *res : std::as_const(resources)) { - if (leakCheck) + for (auto it = resources.cbegin(), end = resources.cend(); it != end; ++it) { + QRhiResource *res = it.key(); + const bool ownsNativeResources = it.value(); + if (leakCheck && ownsNativeResources) qWarning(" %s resource %p (%s)", resourceTypeStr(res), res, res->m_objectName.constData()); // Null out the resource's rhi pointer. This is why it makes sense to do null diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h index 7b2128024f..6641bf5822 100644 --- a/src/gui/rhi/qrhi_p_p.h +++ b/src/gui/rhi/qrhi_p_p.h @@ -149,10 +149,14 @@ public: void textureFormatInfo(QRhiTexture::Format format, const QSize &size, quint32 *bpl, quint32 *byteSize, quint32 *bytesPerPixel) const; - // only really care about resources that own native graphics resources underneath - void registerResource(QRhiResource *res) + void registerResource(QRhiResource *res, bool ownsNativeResources = true) { - resources.insert(res); + // The ownsNativeResources is relevant for the (graphics resource) leak + // check in ~QRhiImplementation; when false, the registration's sole + // purpose is to automatically null out the resource's m_rhi pointer in + // case the rhi goes away first. (which should not happen in + // well-written applications but we try to be graceful) + resources.insert(res, ownsNativeResources); } void unregisterResource(QRhiResource *res) @@ -160,11 +164,6 @@ public: resources.remove(res); } - QSet<QRhiResource *> activeResources() const - { - return resources; - } - void addDeleteLater(QRhiResource *res) { if (inFrame) @@ -251,7 +250,7 @@ private: QVarLengthArray<QRhiResourceUpdateBatch *, 4> resUpdPool; quint64 resUpdPoolMap = 0; int lastResUpdIdx = -1; - QSet<QRhiResource *> resources; + QHash<QRhiResource *, bool> resources; QSet<QRhiResource *> pendingDeleteResources; QVarLengthArray<QRhi::CleanupCallback, 4> cleanupCallbacks; QVarLengthArray<QRhi::GpuFrameTimeCallback, 4> gpuFrameTimeCallbacks; diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 15b713192e..a52754b0a7 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -3588,7 +3588,9 @@ QD3D11RenderPassDescriptor::~QD3D11RenderPassDescriptor() void QD3D11RenderPassDescriptor::destroy() { - // nothing to do here + QRHI_RES_RHI(QRhiD3D11); + if (rhiD) + rhiD->unregisterResource(this); } bool QD3D11RenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const @@ -3599,7 +3601,10 @@ bool QD3D11RenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *ot QRhiRenderPassDescriptor *QD3D11RenderPassDescriptor::newCompatibleRenderPassDescriptor() const { - return new QD3D11RenderPassDescriptor(m_rhi); + QD3D11RenderPassDescriptor *rpD = new QD3D11RenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiD3D11); + rhiD->registerResource(rpD, false); + return rpD; } QVector<quint32> QD3D11RenderPassDescriptor::serializedFormat() const @@ -3681,7 +3686,10 @@ void QD3D11TextureRenderTarget::destroy() QRhiRenderPassDescriptor *QD3D11TextureRenderTarget::newCompatibleRenderPassDescriptor() { - return new QD3D11RenderPassDescriptor(m_rhi); + QD3D11RenderPassDescriptor *rpD = new QD3D11RenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiD3D11); + rhiD->registerResource(rpD, false); + return rpD; } bool QD3D11TextureRenderTarget::create() @@ -3845,6 +3853,10 @@ void QD3D11ShaderResourceBindings::destroy() { sortedBindings.clear(); boundResourceData.clear(); + + QRHI_RES_RHI(QRhiD3D11); + if (rhiD) + rhiD->unregisterResource(this); } bool QD3D11ShaderResourceBindings::create() @@ -3876,6 +3888,7 @@ bool QD3D11ShaderResourceBindings::create() } generation += 1; + rhiD->registerResource(this, false); return true; } @@ -4796,7 +4809,10 @@ QRhiSwapChainHdrInfo QD3D11SwapChain::hdrInfo() QRhiRenderPassDescriptor *QD3D11SwapChain::newCompatibleRenderPassDescriptor() { - return new QD3D11RenderPassDescriptor(m_rhi); + QD3D11RenderPassDescriptor *rpD = new QD3D11RenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiD3D11); + rhiD->registerResource(rpD, false); + return rpD; } bool QD3D11SwapChain::newColorBuffer(const QSize &size, DXGI_FORMAT format, DXGI_SAMPLE_DESC sampleDesc, diff --git a/src/gui/rhi/qrhid3d12.cpp b/src/gui/rhi/qrhid3d12.cpp index d80fe8a406..78f8339807 100644 --- a/src/gui/rhi/qrhid3d12.cpp +++ b/src/gui/rhi/qrhid3d12.cpp @@ -4168,6 +4168,10 @@ QD3D12Sampler::~QD3D12Sampler() void QD3D12Sampler::destroy() { shaderVisibleDescriptor = {}; + + QRHI_RES_RHI(QRhiD3D12); + if (rhiD) + rhiD->unregisterResource(this); } static inline D3D12_FILTER toD3DFilter(QRhiSampler::Filter minFilter, QRhiSampler::Filter magFilter, QRhiSampler::Filter mipFilter) @@ -4248,6 +4252,9 @@ bool QD3D12Sampler::create() desc.MaxAnisotropy = 1.0f; desc.ComparisonFunc = toD3DTextureComparisonFunc(m_compareOp); desc.MaxLOD = m_mipmapMode == None ? 0.0f : 10000.0f; + + QRHI_RES_RHI(QRhiD3D12); + rhiD->registerResource(this, false); return true; } @@ -4326,6 +4333,8 @@ QRhiRenderPassDescriptor *QD3D12TextureRenderTarget::newCompatibleRenderPassDesc rpD->updateSerializedFormat(); + QRHI_RES_RHI(QRhiD3D12); + rhiD->registerResource(rpD); return rpD; } @@ -4499,6 +4508,10 @@ QD3D12ShaderResourceBindings::~QD3D12ShaderResourceBindings() void QD3D12ShaderResourceBindings::destroy() { sortedBindings.clear(); + + QRHI_RES_RHI(QRhiD3D12); + if (rhiD) + rhiD->unregisterResource(this); } bool QD3D12ShaderResourceBindings::create() @@ -4533,6 +4546,7 @@ bool QD3D12ShaderResourceBindings::create() // therefore impossible. generation += 1; + rhiD->registerResource(this, false); return true; } @@ -5464,7 +5478,9 @@ QD3D12RenderPassDescriptor::~QD3D12RenderPassDescriptor() void QD3D12RenderPassDescriptor::destroy() { - // nothing to do here + QRHI_RES_RHI(QRhiD3D12); + if (rhiD) + rhiD->unregisterResource(this); } bool QD3D12RenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const @@ -5507,13 +5523,17 @@ void QD3D12RenderPassDescriptor::updateSerializedFormat() QRhiRenderPassDescriptor *QD3D12RenderPassDescriptor::newCompatibleRenderPassDescriptor() const { - QD3D12RenderPassDescriptor *rp = new QD3D12RenderPassDescriptor(m_rhi); - rp->colorAttachmentCount = colorAttachmentCount; - rp->hasDepthStencil = hasDepthStencil; - memcpy(rp->colorFormat, colorFormat, sizeof(colorFormat)); - rp->dsFormat = dsFormat; - rp->updateSerializedFormat(); - return rp; + QD3D12RenderPassDescriptor *rpD = new QD3D12RenderPassDescriptor(m_rhi); + rpD->colorAttachmentCount = colorAttachmentCount; + rpD->hasDepthStencil = hasDepthStencil; + memcpy(rpD->colorFormat, colorFormat, sizeof(colorFormat)); + rpD->dsFormat = dsFormat; + + rpD->updateSerializedFormat(); + + QRHI_RES_RHI(QRhiD3D12); + rhiD->registerResource(rpD); + return rpD; } QVector<quint32> QD3D12RenderPassDescriptor::serializedFormat() const @@ -5756,6 +5776,9 @@ QRhiRenderPassDescriptor *QD3D12SwapChain::newCompatibleRenderPassDescriptor() rpD->colorFormat[0] = int(srgbAdjustedColorFormat); rpD->dsFormat = QD3D12RenderBuffer::DS_FORMAT; rpD->updateSerializedFormat(); + + QRHI_RES_RHI(QRhiD3D12); + rhiD->registerResource(rpD); return rpD; } diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 7c879a391b..acdf1ec04c 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -5334,7 +5334,9 @@ QGles2Sampler::~QGles2Sampler() void QGles2Sampler::destroy() { - // nothing to do here + QRHI_RES_RHI(QRhiGles2); + if (rhiD) + rhiD->unregisterResource(this); } bool QGles2Sampler::create() @@ -5347,6 +5349,8 @@ bool QGles2Sampler::create() d.gltexcomparefunc = toGlTextureCompareFunc(m_compareOp); generation += 1; + QRHI_RES_RHI(QRhiGles2); + rhiD->registerResource(this, false); return true; } @@ -5363,7 +5367,9 @@ QGles2RenderPassDescriptor::~QGles2RenderPassDescriptor() void QGles2RenderPassDescriptor::destroy() { - // nothing to do here + QRHI_RES_RHI(QRhiGles2); + if (rhiD) + rhiD->unregisterResource(this); } bool QGles2RenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const @@ -5374,7 +5380,10 @@ bool QGles2RenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *ot QRhiRenderPassDescriptor *QGles2RenderPassDescriptor::newCompatibleRenderPassDescriptor() const { - return new QGles2RenderPassDescriptor(m_rhi); + QGles2RenderPassDescriptor *rpD = new QGles2RenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiGles2); + rhiD->registerResource(rpD, false); + return rpD; } QVector<quint32> QGles2RenderPassDescriptor::serializedFormat() const @@ -5447,7 +5456,10 @@ void QGles2TextureRenderTarget::destroy() QRhiRenderPassDescriptor *QGles2TextureRenderTarget::newCompatibleRenderPassDescriptor() { - return new QGles2RenderPassDescriptor(m_rhi); + QGles2RenderPassDescriptor *rpD = new QGles2RenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiGles2); + rhiD->registerResource(rpD, false); + return rpD; } bool QGles2TextureRenderTarget::create() @@ -5594,7 +5606,9 @@ QGles2ShaderResourceBindings::~QGles2ShaderResourceBindings() void QGles2ShaderResourceBindings::destroy() { - // nothing to do here + QRHI_RES_RHI(QRhiGles2); + if (rhiD) + rhiD->unregisterResource(this); } bool QGles2ShaderResourceBindings::create() @@ -5617,6 +5631,7 @@ bool QGles2ShaderResourceBindings::create() rhiD->updateLayoutDesc(this); generation += 1; + rhiD->registerResource(this, false); return true; } @@ -5981,7 +5996,10 @@ bool QGles2SwapChain::isFormatSupported(Format f) QRhiRenderPassDescriptor *QGles2SwapChain::newCompatibleRenderPassDescriptor() { - return new QGles2RenderPassDescriptor(m_rhi); + QGles2RenderPassDescriptor *rpD = new QGles2RenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiGles2); + rhiD->registerResource(rpD, false); + return rpD; } void QGles2SwapChain::initSwapChainRenderTarget(QGles2SwapChainRenderTarget *rt) @@ -6030,7 +6048,7 @@ bool QGles2SwapChain::createOrResize() // implement a safe destroy(). if (needsRegistration) { QRHI_RES_RHI(QRhiGles2); - rhiD->registerResource(this); + rhiD->registerResource(this, false); } return true; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 8666c4b032..b05b35f81c 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -3930,7 +3930,9 @@ QMetalRenderPassDescriptor::~QMetalRenderPassDescriptor() void QMetalRenderPassDescriptor::destroy() { - // nothing to do here + QRHI_RES_RHI(QRhiMetal); + if (rhiD) + rhiD->unregisterResource(this); } bool QMetalRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const @@ -3973,13 +3975,17 @@ void QMetalRenderPassDescriptor::updateSerializedFormat() QRhiRenderPassDescriptor *QMetalRenderPassDescriptor::newCompatibleRenderPassDescriptor() const { - QMetalRenderPassDescriptor *rp = new QMetalRenderPassDescriptor(m_rhi); - rp->colorAttachmentCount = colorAttachmentCount; - rp->hasDepthStencil = hasDepthStencil; - memcpy(rp->colorFormat, colorFormat, sizeof(colorFormat)); - rp->dsFormat = dsFormat; - rp->updateSerializedFormat(); - return rp; + QMetalRenderPassDescriptor *rpD = new QMetalRenderPassDescriptor(m_rhi); + rpD->colorAttachmentCount = colorAttachmentCount; + rpD->hasDepthStencil = hasDepthStencil; + memcpy(rpD->colorFormat, colorFormat, sizeof(colorFormat)); + rpD->dsFormat = dsFormat; + + rpD->updateSerializedFormat(); + + QRHI_RES_RHI(QRhiMetal); + rhiD->registerResource(rpD, false); + return rpD; } QVector<quint32> QMetalRenderPassDescriptor::serializedFormat() const @@ -4035,7 +4041,9 @@ QMetalTextureRenderTarget::~QMetalTextureRenderTarget() void QMetalTextureRenderTarget::destroy() { - // nothing to do here + QRHI_RES_RHI(QRhiMetal); + if (rhiD) + rhiD->unregisterResource(this); } QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDescriptor() @@ -4058,6 +4066,9 @@ QRhiRenderPassDescriptor *QMetalTextureRenderTarget::newCompatibleRenderPassDesc rpD->dsFormat = int(QRHI_RES(QMetalRenderBuffer, m_desc.depthStencilBuffer())->d->format); rpD->updateSerializedFormat(); + + QRHI_RES_RHI(QRhiMetal); + rhiD->registerResource(rpD, false); return rpD; } @@ -4131,6 +4142,7 @@ bool QMetalTextureRenderTarget::create() QRhiRenderTargetAttachmentTracker::updateResIdList<QMetalTexture, QMetalRenderBuffer>(m_desc, &d->currentResIdList); + rhiD->registerResource(this, false); return true; } @@ -4166,6 +4178,10 @@ void QMetalShaderResourceBindings::destroy() { sortedBindings.clear(); maxBinding = -1; + + QRHI_RES_RHI(QRhiMetal); + if (rhiD) + rhiD->unregisterResource(this); } bool QMetalShaderResourceBindings::create() @@ -4192,6 +4208,7 @@ bool QMetalShaderResourceBindings::create() memset(&bd, 0, sizeof(BoundResourceData)); generation += 1; + rhiD->registerResource(this, false); return true; } @@ -6053,6 +6070,8 @@ bool QMetalSwapChain::isFormatSupported(Format f) QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor() { + QRHI_RES_RHI(QRhiMetal); + chooseFormats(); // ensure colorFormat and similar are filled out QMetalRenderPassDescriptor *rpD = new QMetalRenderPassDescriptor(m_rhi); @@ -6063,7 +6082,6 @@ QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor() #ifdef Q_OS_MACOS // m_depthStencil may not be built yet so cannot rely on computed fields in it - QRHI_RES_RHI(QRhiMetal); rpD->dsFormat = rhiD->d->dev.depth24Stencil8PixelFormatSupported ? MTLPixelFormatDepth24Unorm_Stencil8 : MTLPixelFormatDepth32Float_Stencil8; #else @@ -6071,6 +6089,8 @@ QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor() #endif rpD->updateSerializedFormat(); + + rhiD->registerResource(rpD, false); return rpD; } diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 84220a3a65..40870aab6a 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -716,10 +716,15 @@ QNullSampler::~QNullSampler() void QNullSampler::destroy() { + QRHI_RES_RHI(QRhiNull); + if (rhiD) + rhiD->unregisterResource(this); } bool QNullSampler::create() { + QRHI_RES_RHI(QRhiNull); + rhiD->registerResource(this); return true; } @@ -735,6 +740,9 @@ QNullRenderPassDescriptor::~QNullRenderPassDescriptor() void QNullRenderPassDescriptor::destroy() { + QRHI_RES_RHI(QRhiNull); + if (rhiD) + rhiD->unregisterResource(this); } bool QNullRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *other) const @@ -745,7 +753,10 @@ bool QNullRenderPassDescriptor::isCompatible(const QRhiRenderPassDescriptor *oth QRhiRenderPassDescriptor *QNullRenderPassDescriptor::newCompatibleRenderPassDescriptor() const { - return new QNullRenderPassDescriptor(m_rhi); + QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiNull); + rhiD->registerResource(rpD, false); + return rpD; } QVector<quint32> QNullRenderPassDescriptor::serializedFormat() const @@ -798,11 +809,17 @@ QNullTextureRenderTarget::~QNullTextureRenderTarget() void QNullTextureRenderTarget::destroy() { + QRHI_RES_RHI(QRhiNull); + if (rhiD) + rhiD->unregisterResource(this); } QRhiRenderPassDescriptor *QNullTextureRenderTarget::newCompatibleRenderPassDescriptor() { - return new QNullRenderPassDescriptor(m_rhi); + QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiNull); + rhiD->registerResource(rpD, false); + return rpD; } bool QNullTextureRenderTarget::create() @@ -820,6 +837,7 @@ bool QNullTextureRenderTarget::create() d.pixelSize = m_desc.depthTexture()->pixelSize(); } QRhiRenderTargetAttachmentTracker::updateResIdList<QNullTexture, QNullRenderBuffer>(m_desc, &d.currentResIdList); + rhiD->registerResource(this); return true; } @@ -853,6 +871,9 @@ QNullShaderResourceBindings::~QNullShaderResourceBindings() void QNullShaderResourceBindings::destroy() { + QRHI_RES_RHI(QRhiNull); + if (rhiD) + rhiD->unregisterResource(this); } bool QNullShaderResourceBindings::create() @@ -863,6 +884,7 @@ bool QNullShaderResourceBindings::create() rhiD->updateLayoutDesc(this); + rhiD->registerResource(this, false); return true; } @@ -883,6 +905,9 @@ QNullGraphicsPipeline::~QNullGraphicsPipeline() void QNullGraphicsPipeline::destroy() { + QRHI_RES_RHI(QRhiNull); + if (rhiD) + rhiD->unregisterResource(this); } bool QNullGraphicsPipeline::create() @@ -891,6 +916,7 @@ bool QNullGraphicsPipeline::create() if (!rhiD->sanityCheckGraphicsPipeline(this)) return false; + rhiD->registerResource(this); return true; } @@ -906,10 +932,15 @@ QNullComputePipeline::~QNullComputePipeline() void QNullComputePipeline::destroy() { + QRHI_RES_RHI(QRhiNull); + if (rhiD) + rhiD->unregisterResource(this); } bool QNullComputePipeline::create() { + QRHI_RES_RHI(QRhiNull); + rhiD->registerResource(this); return true; } @@ -969,7 +1000,10 @@ bool QNullSwapChain::isFormatSupported(Format f) QRhiRenderPassDescriptor *QNullSwapChain::newCompatibleRenderPassDescriptor() { - return new QNullRenderPassDescriptor(m_rhi); + QNullRenderPassDescriptor *rpD = new QNullRenderPassDescriptor(m_rhi); + QRHI_RES_RHI(QRhiNull); + rhiD->registerResource(rpD, false); + return rpD; } bool QNullSwapChain::createOrResize() diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index 91e573c611..b0f071bbd0 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -5450,12 +5450,36 @@ void tst_QRhi::leakedResourceDestroy() rt->setRenderPassDescriptor(rpDesc.data()); QVERIFY(rt->create()); + QRhiRenderBuffer *rb = rhi->newRenderBuffer(QRhiRenderBuffer::DepthStencil, QSize(512, 512)); + QVERIFY(rb->create()); + + QRhiShaderResourceBindings *srb = rhi->newShaderResourceBindings(); + QVERIFY(srb->create()); + if (impl == QRhi::Vulkan) qDebug("Vulkan validation layer warnings may be printed below - this is expected"); + if (impl == QRhi::D3D12) + qDebug("QD3D12CpuDescriptorPool warnings may be printed below - this is expected"); + + qDebug("QRhi resource leak check warnings may be printed below - this is expected"); + + // make the QRhi go away early rhi.reset(); - // let the scoped ptr do its job with the resources + // see if the internal rhi backpointer got nulled out + QVERIFY(buffer->rhi() == nullptr); + QVERIFY(texture->rhi() == nullptr); + QVERIFY(rt->rhi() == nullptr); + QVERIFY(rpDesc->rhi() == nullptr); + QVERIFY(rb->rhi() == nullptr); + QVERIFY(srb->rhi() == nullptr); + + // test out deleteLater on some of the resources + rb->deleteLater(); + srb->deleteLater(); + + // let the scoped ptr do its job with the rest } void tst_QRhi::renderToFloatTexture_data() |