diff options
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 8 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p.h | 7 | ||||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/tst_qrhi.cpp | 16 |
3 files changed, 30 insertions, 1 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index e79dc1e822..1578bf0fd4 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -3002,6 +3002,7 @@ QRhiResource::Type QRhiTextureRenderTarget::resourceType() const QRhiShaderResourceBindings::QRhiShaderResourceBindings(QRhiImplementation *rhi) : QRhiResource(rhi) { + m_layoutDesc.reserve(BINDING_PREALLOC * LAYOUT_DESC_FIELD_COUNT); } /*! @@ -5620,6 +5621,13 @@ void QRhiCommandBuffer::setGraphicsPipeline(QRhiGraphicsPipeline *ps) srb. In this case setShaderResources() must be called even if \a srb is the same as in the last call. + When \a srb is not null, the QRhiShaderResourceBindings object the pipeline + was built with in create() is guaranteed to be not accessed in any form. In + fact, it does not need to be valid even at this point: destroying the + pipeline's associated srb after create() and instead explicitly specifying + another, \l{QRhiShaderResourceBindings::isLayoutCompatible()}{layout + compatible} one in every setShaderResources() call is valid. + \a dynamicOffsets allows specifying buffer offsets for uniform buffers that were associated with \a srb via QRhiShaderResourceBinding::uniformBufferWithDynamicOffset(). This is diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 1e570e8818..8c3e0fdfb2 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1037,6 +1037,8 @@ public: bool isLayoutCompatible(const QRhiShaderResourceBindings *other) const; + QVector<uint> serializedLayoutDescription() const { return m_layoutDesc; } + virtual bool create() = 0; enum UpdateFlag { @@ -1052,7 +1054,10 @@ protected: QRhiShaderResourceBindings(QRhiImplementation *rhi); QVarLengthArray<QRhiShaderResourceBinding, BINDING_PREALLOC> m_bindings; uint m_layoutDescHash = 0; - QVarLengthArray<uint, BINDING_PREALLOC * LAYOUT_DESC_FIELD_COUNT> m_layoutDesc; + // Intentionally not using QVLA for m_layoutDesc: clients like Qt Quick are much + // better served with an implicitly shared container here, because they will likely + // throw this directly into structs serving as cache keys. + QVector<uint> m_layoutDesc; friend class QRhiImplementation; #ifndef QT_NO_DEBUG_STREAM friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBindings &); diff --git a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp index be825c8ac2..61e19434e0 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -3271,6 +3271,8 @@ void tst_QRhi::srbLayoutCompatibility() QVERIFY(srb1->isLayoutCompatible(srb2.data())); QVERIFY(srb2->isLayoutCompatible(srb1.data())); + + QCOMPARE(srb1->serializedLayoutDescription(), srb2->serializedLayoutDescription()); } // different count (not compatible) @@ -3286,6 +3288,8 @@ void tst_QRhi::srbLayoutCompatibility() QVERIFY(!srb1->isLayoutCompatible(srb2.data())); QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + + QVERIFY(srb1->serializedLayoutDescription() != srb2->serializedLayoutDescription()); } // full match (compatible) @@ -3306,6 +3310,10 @@ void tst_QRhi::srbLayoutCompatibility() QVERIFY(srb1->isLayoutCompatible(srb2.data())); QVERIFY(srb2->isLayoutCompatible(srb1.data())); + + QVERIFY(!srb1->serializedLayoutDescription().isEmpty()); + QVERIFY(!srb2->serializedLayoutDescription().isEmpty()); + QCOMPARE(srb1->serializedLayoutDescription(), srb2->serializedLayoutDescription()); } // different visibility (not compatible) @@ -3324,6 +3332,8 @@ void tst_QRhi::srbLayoutCompatibility() QVERIFY(!srb1->isLayoutCompatible(srb2.data())); QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + + QVERIFY(srb1->serializedLayoutDescription() != srb2->serializedLayoutDescription()); } // different binding points (not compatible) @@ -3342,6 +3352,8 @@ void tst_QRhi::srbLayoutCompatibility() QVERIFY(!srb1->isLayoutCompatible(srb2.data())); QVERIFY(!srb2->isLayoutCompatible(srb1.data())); + + QVERIFY(srb1->serializedLayoutDescription() != srb2->serializedLayoutDescription()); } // different buffer region offset and size (compatible) @@ -3362,6 +3374,8 @@ void tst_QRhi::srbLayoutCompatibility() QVERIFY(srb1->isLayoutCompatible(srb2.data())); QVERIFY(srb2->isLayoutCompatible(srb1.data())); + + QCOMPARE(srb1->serializedLayoutDescription(), srb2->serializedLayoutDescription()); } // different resources (compatible) @@ -3382,6 +3396,8 @@ void tst_QRhi::srbLayoutCompatibility() QVERIFY(srb1->isLayoutCompatible(srb2.data())); QVERIFY(srb2->isLayoutCompatible(srb1.data())); + + QCOMPARE(srb1->serializedLayoutDescription(), srb2->serializedLayoutDescription()); } } |