diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2021-09-06 18:06:33 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-09-07 13:19:18 +0000 |
commit | 8f52022bbdd6aae40539191ce9db8b87328fe5b6 (patch) | |
tree | 7451f594fa2979d3a08460668b8661c1eea9d261 | |
parent | 6b6475539815f73dcab5ccf94ea33fd54fcb23bf (diff) |
rhi: Enable serializing a layout description without baking an srb
Change-Id: I66d28cc9d5417bcd5d192fa100c21f69fd42fd6b
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
(cherry picked from commit 4cde0e484c009415397430050cde389fb9b445b6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 11 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p.h | 30 | ||||
-rw-r--r-- | tests/auto/gui/rhi/qrhi/tst_qrhi.cpp | 9 |
3 files changed, 40 insertions, 10 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 1578bf0fd4..420e70cecf 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -3002,7 +3002,7 @@ QRhiResource::Type QRhiTextureRenderTarget::resourceType() const QRhiShaderResourceBindings::QRhiShaderResourceBindings(QRhiImplementation *rhi) : QRhiResource(rhi) { - m_layoutDesc.reserve(BINDING_PREALLOC * LAYOUT_DESC_FIELD_COUNT); + m_layoutDesc.reserve(BINDING_PREALLOC * QRhiShaderResourceBinding::LAYOUT_DESC_ENTRIES_PER_BINDING); } /*! @@ -3053,13 +3053,12 @@ void QRhiImplementation::updateLayoutDesc(QRhiShaderResourceBindings *srb) { srb->m_layoutDescHash = 0; srb->m_layoutDesc.clear(); + auto layoutDescAppender = std::back_inserter(srb->m_layoutDesc); for (const QRhiShaderResourceBinding &b : qAsConst(srb->m_bindings)) { const QRhiShaderResourceBinding::Data *d = b.data(); - // the logic must match QRhiShaderResourceBinding::isLayoutCompatible() - const int count = d->type == QRhiShaderResourceBinding::SampledTexture ? d->u.stex.count : 1; - // the number of entries here should match LAYOUT_DESC_FIELD_COUNT - srb->m_layoutDescHash ^= uint(d->binding) ^ uint(d->stage) ^ uint(d->type) ^ uint(count); - srb->m_layoutDesc << uint(d->binding) << uint(d->stage) << uint(d->type) << uint(count); + srb->m_layoutDescHash ^= uint(d->binding) ^ uint(d->stage) ^ uint(d->type) + ^ uint(d->type == QRhiShaderResourceBinding::SampledTexture ? d->u.stex.count : 1); + d->serialize(layoutDescAppender); } } diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 8c3e0fdfb2..81b00cd07f 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -411,11 +411,34 @@ public: StorageImageData simage; StorageBufferData sbuf; } u; + + template<typename Output> + void serialize(Output dst) const + { + // must write out exactly LAYOUT_DESC_ENTRIES_PER_BINDING elements here + *dst++ = quint32(binding); + *dst++ = quint32(stage); + *dst++ = quint32(type); + *dst++ = quint32(type == QRhiShaderResourceBinding::SampledTexture ? u.stex.count : 1); + } }; Data *data() { return &d; } const Data *data() const { return &d; } + static const int LAYOUT_DESC_ENTRIES_PER_BINDING = 4; + + template<typename Output> + static void serializeLayoutDescription(const QRhiShaderResourceBinding *first, + const QRhiShaderResourceBinding *last, + Output dst) + { + while (first != last) { + first->data()->serialize(dst); + ++first; + } + } + private: Data d; }; @@ -1037,7 +1060,7 @@ public: bool isLayoutCompatible(const QRhiShaderResourceBindings *other) const; - QVector<uint> serializedLayoutDescription() const { return m_layoutDesc; } + QVector<quint32> serializedLayoutDescription() const { return m_layoutDesc; } virtual bool create() = 0; @@ -1050,14 +1073,13 @@ public: protected: static const int BINDING_PREALLOC = 12; - static const int LAYOUT_DESC_FIELD_COUNT = 4; QRhiShaderResourceBindings(QRhiImplementation *rhi); QVarLengthArray<QRhiShaderResourceBinding, BINDING_PREALLOC> m_bindings; - uint m_layoutDescHash = 0; + size_t m_layoutDescHash = 0; // 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; + QVector<quint32> 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 61e19434e0..603acc03de 100644 --- a/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp +++ b/tests/auto/gui/rhi/qrhi/tst_qrhi.cpp @@ -3314,6 +3314,15 @@ void tst_QRhi::srbLayoutCompatibility() QVERIFY(!srb1->serializedLayoutDescription().isEmpty()); QVERIFY(!srb2->serializedLayoutDescription().isEmpty()); QCOMPARE(srb1->serializedLayoutDescription(), srb2->serializedLayoutDescription()); + + // see what we would get if a binding list got serialized "manually", without pulling it out from the srb after building + // (the results should be identical) + QVector<quint32> layoutDesc1; + QRhiShaderResourceBinding::serializeLayoutDescription(srb1->cbeginBindings(), srb1->cendBindings(), std::back_inserter(layoutDesc1)); + QCOMPARE(layoutDesc1, srb1->serializedLayoutDescription()); + QVector<quint32> layoutDesc2; + QRhiShaderResourceBinding::serializeLayoutDescription(srb2->cbeginBindings(), srb2->cendBindings(), std::back_inserter(layoutDesc2)); + QCOMPARE(layoutDesc2, srb2->serializedLayoutDescription()); } // different visibility (not compatible) |