rhi: Enable serializing a layout description without baking an srb
Pick-to: 6.2 Change-Id: I66d28cc9d5417bcd5d192fa100c21f69fd42fd6b Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
parent
b6b0c33058
commit
4cde0e484c
@ -2996,7 +2996,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);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3047,13 +3047,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 &);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user