De-d-pointer QRhiShaderResourceBinding
Sad to see this go since the d pointer pattern with implicit sharing would have been perfect for this class, had this been a public API. However, as binary compatibility will not be a concern for QRhi classes, it is wasteful to allocate memory on every QRhiShaderResourceBinding. This allows users, such as Qt Quick, to use QRhiShaderResourceBinding as a cheap, simple, value class, without having to invent their own alternatives in performance critical places. The change brings a not insignficant improvement in certain qmlbench scenes (the ones with thousands of unbatched geometry nodes). Change-Id: I6d1dced6498d9ad625f90ead78bc0a417ea99ed8 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
This commit is contained in:
parent
e1ed2c3864
commit
d4c17725ab
@ -2645,43 +2645,10 @@ bool QRhiShaderResourceBindings::isLayoutCompatible(const QRhiShaderResourceBind
|
|||||||
\internal
|
\internal
|
||||||
*/
|
*/
|
||||||
QRhiShaderResourceBinding::QRhiShaderResourceBinding()
|
QRhiShaderResourceBinding::QRhiShaderResourceBinding()
|
||||||
: d(new QRhiShaderResourceBindingPrivate)
|
|
||||||
{
|
{
|
||||||
}
|
// Zero out everything, including possible padding, because will use
|
||||||
|
// qHashBits on it.
|
||||||
/*!
|
memset(&d.u, 0, sizeof(d.u));
|
||||||
\internal
|
|
||||||
*/
|
|
||||||
void QRhiShaderResourceBinding::detach()
|
|
||||||
{
|
|
||||||
qAtomicDetach(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\internal
|
|
||||||
*/
|
|
||||||
QRhiShaderResourceBinding::QRhiShaderResourceBinding(const QRhiShaderResourceBinding &other)
|
|
||||||
: d(other.d)
|
|
||||||
{
|
|
||||||
d->ref.ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\internal
|
|
||||||
*/
|
|
||||||
QRhiShaderResourceBinding &QRhiShaderResourceBinding::operator=(const QRhiShaderResourceBinding &other)
|
|
||||||
{
|
|
||||||
qAtomicAssign(d, other.d);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Destructor.
|
|
||||||
*/
|
|
||||||
QRhiShaderResourceBinding::~QRhiShaderResourceBinding()
|
|
||||||
{
|
|
||||||
if (!d->ref.deref())
|
|
||||||
delete d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2698,8 +2665,7 @@ QRhiShaderResourceBinding::~QRhiShaderResourceBinding()
|
|||||||
*/
|
*/
|
||||||
bool QRhiShaderResourceBinding::isLayoutCompatible(const QRhiShaderResourceBinding &other) const
|
bool QRhiShaderResourceBinding::isLayoutCompatible(const QRhiShaderResourceBinding &other) const
|
||||||
{
|
{
|
||||||
return (d == other.d)
|
return d.binding == other.d.binding && d.stage == other.d.stage && d.type == other.d.type;
|
||||||
|| (d->binding == other.d->binding && d->stage == other.d->stage && d->type == other.d->type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -2712,15 +2678,13 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBuffer(
|
|||||||
int binding, StageFlags stage, QRhiBuffer *buf)
|
int binding, StageFlags stage, QRhiBuffer *buf)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b;
|
QRhiShaderResourceBinding b;
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.binding = binding;
|
||||||
Q_ASSERT(d->ref.loadRelaxed() == 1);
|
b.d.stage = stage;
|
||||||
d->binding = binding;
|
b.d.type = UniformBuffer;
|
||||||
d->stage = stage;
|
b.d.u.ubuf.buf = buf;
|
||||||
d->type = UniformBuffer;
|
b.d.u.ubuf.offset = 0;
|
||||||
d->u.ubuf.buf = buf;
|
b.d.u.ubuf.maybeSize = 0; // entire buffer
|
||||||
d->u.ubuf.offset = 0;
|
b.d.u.ubuf.hasDynamicOffset = false;
|
||||||
d->u.ubuf.maybeSize = 0; // entire buffer
|
|
||||||
d->u.ubuf.hasDynamicOffset = false;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2741,9 +2705,8 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBuffer(
|
|||||||
{
|
{
|
||||||
Q_ASSERT(size > 0);
|
Q_ASSERT(size > 0);
|
||||||
QRhiShaderResourceBinding b = uniformBuffer(binding, stage, buf);
|
QRhiShaderResourceBinding b = uniformBuffer(binding, stage, buf);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.u.ubuf.offset = offset;
|
||||||
d->u.ubuf.offset = offset;
|
b.d.u.ubuf.maybeSize = size;
|
||||||
d->u.ubuf.maybeSize = size;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2762,8 +2725,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::uniformBufferWithDynamicOff
|
|||||||
int binding, StageFlags stage, QRhiBuffer *buf, int size)
|
int binding, StageFlags stage, QRhiBuffer *buf, int size)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b = uniformBuffer(binding, stage, buf, 0, size);
|
QRhiShaderResourceBinding b = uniformBuffer(binding, stage, buf, 0, size);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.u.ubuf.hasDynamicOffset = true;
|
||||||
d->u.ubuf.hasDynamicOffset = true;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2776,13 +2738,11 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::sampledTexture(
|
|||||||
int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
|
int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b;
|
QRhiShaderResourceBinding b;
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.binding = binding;
|
||||||
Q_ASSERT(d->ref.loadRelaxed() == 1);
|
b.d.stage = stage;
|
||||||
d->binding = binding;
|
b.d.type = SampledTexture;
|
||||||
d->stage = stage;
|
b.d.u.stex.tex = tex;
|
||||||
d->type = SampledTexture;
|
b.d.u.stex.sampler = sampler;
|
||||||
d->u.stex.tex = tex;
|
|
||||||
d->u.stex.sampler = sampler;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2798,13 +2758,11 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::imageLoad(
|
|||||||
int binding, StageFlags stage, QRhiTexture *tex, int level)
|
int binding, StageFlags stage, QRhiTexture *tex, int level)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b;
|
QRhiShaderResourceBinding b;
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.binding = binding;
|
||||||
Q_ASSERT(d->ref.loadRelaxed() == 1);
|
b.d.stage = stage;
|
||||||
d->binding = binding;
|
b.d.type = ImageLoad;
|
||||||
d->stage = stage;
|
b.d.u.simage.tex = tex;
|
||||||
d->type = ImageLoad;
|
b.d.u.simage.level = level;
|
||||||
d->u.simage.tex = tex;
|
|
||||||
d->u.simage.level = level;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2820,8 +2778,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::imageStore(
|
|||||||
int binding, StageFlags stage, QRhiTexture *tex, int level)
|
int binding, StageFlags stage, QRhiTexture *tex, int level)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b = imageLoad(binding, stage, tex, level);
|
QRhiShaderResourceBinding b = imageLoad(binding, stage, tex, level);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.type = ImageStore;
|
||||||
d->type = ImageStore;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2837,8 +2794,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::imageLoadStore(
|
|||||||
int binding, StageFlags stage, QRhiTexture *tex, int level)
|
int binding, StageFlags stage, QRhiTexture *tex, int level)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b = imageLoad(binding, stage, tex, level);
|
QRhiShaderResourceBinding b = imageLoad(binding, stage, tex, level);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.type = ImageLoadStore;
|
||||||
d->type = ImageLoadStore;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2852,14 +2808,12 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoad(
|
|||||||
int binding, StageFlags stage, QRhiBuffer *buf)
|
int binding, StageFlags stage, QRhiBuffer *buf)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b;
|
QRhiShaderResourceBinding b;
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.binding = binding;
|
||||||
Q_ASSERT(d->ref.loadRelaxed() == 1);
|
b.d.stage = stage;
|
||||||
d->binding = binding;
|
b.d.type = BufferLoad;
|
||||||
d->stage = stage;
|
b.d.u.sbuf.buf = buf;
|
||||||
d->type = BufferLoad;
|
b.d.u.sbuf.offset = 0;
|
||||||
d->u.sbuf.buf = buf;
|
b.d.u.sbuf.maybeSize = 0; // entire buffer
|
||||||
d->u.sbuf.offset = 0;
|
|
||||||
d->u.sbuf.maybeSize = 0; // entire buffer
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2875,9 +2829,8 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoad(
|
|||||||
{
|
{
|
||||||
Q_ASSERT(size > 0);
|
Q_ASSERT(size > 0);
|
||||||
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
|
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.u.sbuf.offset = offset;
|
||||||
d->u.sbuf.offset = offset;
|
b.d.u.sbuf.maybeSize = size;
|
||||||
d->u.sbuf.maybeSize = size;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2891,8 +2844,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferStore(
|
|||||||
int binding, StageFlags stage, QRhiBuffer *buf)
|
int binding, StageFlags stage, QRhiBuffer *buf)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
|
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.type = BufferStore;
|
||||||
d->type = BufferStore;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2908,9 +2860,8 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferStore(
|
|||||||
{
|
{
|
||||||
Q_ASSERT(size > 0);
|
Q_ASSERT(size > 0);
|
||||||
QRhiShaderResourceBinding b = bufferStore(binding, stage, buf);
|
QRhiShaderResourceBinding b = bufferStore(binding, stage, buf);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.u.sbuf.offset = offset;
|
||||||
d->u.sbuf.offset = offset;
|
b.d.u.sbuf.maybeSize = size;
|
||||||
d->u.sbuf.maybeSize = size;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2924,8 +2875,7 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoadStore(
|
|||||||
int binding, StageFlags stage, QRhiBuffer *buf)
|
int binding, StageFlags stage, QRhiBuffer *buf)
|
||||||
{
|
{
|
||||||
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
|
QRhiShaderResourceBinding b = bufferLoad(binding, stage, buf);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.type = BufferLoadStore;
|
||||||
d->type = BufferLoadStore;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2941,9 +2891,8 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoadStore(
|
|||||||
{
|
{
|
||||||
Q_ASSERT(size > 0);
|
Q_ASSERT(size > 0);
|
||||||
QRhiShaderResourceBinding b = bufferLoadStore(binding, stage, buf);
|
QRhiShaderResourceBinding b = bufferLoadStore(binding, stage, buf);
|
||||||
QRhiShaderResourceBindingPrivate *d = QRhiShaderResourceBindingPrivate::get(&b);
|
b.d.u.sbuf.offset = offset;
|
||||||
d->u.sbuf.offset = offset;
|
b.d.u.sbuf.maybeSize = size;
|
||||||
d->u.sbuf.maybeSize = size;
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2959,28 +2908,32 @@ QRhiShaderResourceBinding QRhiShaderResourceBinding::bufferLoadStore(
|
|||||||
*/
|
*/
|
||||||
bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW
|
bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
if (a.d == b.d)
|
const QRhiShaderResourceBinding::Data *da = a.data();
|
||||||
|
const QRhiShaderResourceBinding::Data *db = b.data();
|
||||||
|
|
||||||
|
if (da == db)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (a.d->binding != b.d->binding
|
|
||||||
|| a.d->stage != b.d->stage
|
if (da->binding != db->binding
|
||||||
|| a.d->type != b.d->type)
|
|| da->stage != db->stage
|
||||||
|
|| da->type != db->type)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (a.d->type) {
|
switch (da->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
if (a.d->u.ubuf.buf != b.d->u.ubuf.buf
|
if (da->u.ubuf.buf != db->u.ubuf.buf
|
||||||
|| a.d->u.ubuf.offset != b.d->u.ubuf.offset
|
|| da->u.ubuf.offset != db->u.ubuf.offset
|
||||||
|| a.d->u.ubuf.maybeSize != b.d->u.ubuf.maybeSize)
|
|| da->u.ubuf.maybeSize != db->u.ubuf.maybeSize)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QRhiShaderResourceBinding::SampledTexture:
|
case QRhiShaderResourceBinding::SampledTexture:
|
||||||
if (a.d->u.stex.tex != b.d->u.stex.tex
|
if (da->u.stex.tex != db->u.stex.tex
|
||||||
|| a.d->u.stex.sampler != b.d->u.stex.sampler)
|
|| da->u.stex.sampler != db->u.stex.sampler)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2990,8 +2943,8 @@ bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
|
|||||||
case QRhiShaderResourceBinding::ImageStore:
|
case QRhiShaderResourceBinding::ImageStore:
|
||||||
Q_FALLTHROUGH();
|
Q_FALLTHROUGH();
|
||||||
case QRhiShaderResourceBinding::ImageLoadStore:
|
case QRhiShaderResourceBinding::ImageLoadStore:
|
||||||
if (a.d->u.simage.tex != b.d->u.simage.tex
|
if (da->u.simage.tex != db->u.simage.tex
|
||||||
|| a.d->u.simage.level != b.d->u.simage.level)
|
|| da->u.simage.level != db->u.simage.level)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3001,9 +2954,9 @@ bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
|
|||||||
case QRhiShaderResourceBinding::BufferStore:
|
case QRhiShaderResourceBinding::BufferStore:
|
||||||
Q_FALLTHROUGH();
|
Q_FALLTHROUGH();
|
||||||
case QRhiShaderResourceBinding::BufferLoadStore:
|
case QRhiShaderResourceBinding::BufferLoadStore:
|
||||||
if (a.d->u.sbuf.buf != b.d->u.sbuf.buf
|
if (da->u.sbuf.buf != db->u.sbuf.buf
|
||||||
|| a.d->u.sbuf.offset != b.d->u.sbuf.offset
|
|| da->u.sbuf.offset != db->u.sbuf.offset
|
||||||
|| a.d->u.sbuf.maybeSize != b.d->u.sbuf.maybeSize)
|
|| da->u.sbuf.maybeSize != db->u.sbuf.maybeSize)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3034,16 +2987,16 @@ bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBind
|
|||||||
*/
|
*/
|
||||||
uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW
|
uint qHash(const QRhiShaderResourceBinding &b, uint seed) Q_DECL_NOTHROW
|
||||||
{
|
{
|
||||||
const char *u = reinterpret_cast<const char *>(&b.d->u);
|
const QRhiShaderResourceBinding::Data *d = b.data();
|
||||||
return seed + uint(b.d->binding) + 10 * uint(b.d->stage) + 100 * uint(b.d->type)
|
return seed + uint(d->binding) + 10 * uint(d->stage) + 100 * uint(d->type)
|
||||||
+ qHash(QByteArray::fromRawData(u, sizeof(b.d->u)), seed);
|
+ qHashBits(&d->u, sizeof(d->u), seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
#ifndef QT_NO_DEBUG_STREAM
|
||||||
QDebug operator<<(QDebug dbg, const QRhiShaderResourceBinding &b)
|
QDebug operator<<(QDebug dbg, const QRhiShaderResourceBinding &b)
|
||||||
{
|
{
|
||||||
const QRhiShaderResourceBindingPrivate *d = b.d;
|
|
||||||
QDebugStateSaver saver(dbg);
|
QDebugStateSaver saver(dbg);
|
||||||
|
const QRhiShaderResourceBinding::Data *d = b.data();
|
||||||
dbg.nospace() << "QRhiShaderResourceBinding("
|
dbg.nospace() << "QRhiShaderResourceBinding("
|
||||||
<< "binding=" << d->binding
|
<< "binding=" << d->binding
|
||||||
<< " stage=" << d->stage
|
<< " stage=" << d->stage
|
||||||
|
@ -320,10 +320,6 @@ public:
|
|||||||
Q_DECLARE_FLAGS(StageFlags, StageFlag)
|
Q_DECLARE_FLAGS(StageFlags, StageFlag)
|
||||||
|
|
||||||
QRhiShaderResourceBinding();
|
QRhiShaderResourceBinding();
|
||||||
QRhiShaderResourceBinding(const QRhiShaderResourceBinding &other);
|
|
||||||
QRhiShaderResourceBinding &operator=(const QRhiShaderResourceBinding &other);
|
|
||||||
~QRhiShaderResourceBinding();
|
|
||||||
void detach();
|
|
||||||
|
|
||||||
bool isLayoutCompatible(const QRhiShaderResourceBinding &other) const;
|
bool isLayoutCompatible(const QRhiShaderResourceBinding &other) const;
|
||||||
|
|
||||||
@ -344,19 +340,49 @@ public:
|
|||||||
static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf);
|
static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf);
|
||||||
static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size);
|
static QRhiShaderResourceBinding bufferLoadStore(int binding, StageFlags stage, QRhiBuffer *buf, int offset, int size);
|
||||||
|
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
int binding;
|
||||||
|
QRhiShaderResourceBinding::StageFlags stage;
|
||||||
|
QRhiShaderResourceBinding::Type type;
|
||||||
|
struct UniformBufferData {
|
||||||
|
QRhiBuffer *buf;
|
||||||
|
int offset;
|
||||||
|
int maybeSize;
|
||||||
|
bool hasDynamicOffset;
|
||||||
|
};
|
||||||
|
struct SampledTextureData {
|
||||||
|
QRhiTexture *tex;
|
||||||
|
QRhiSampler *sampler;
|
||||||
|
};
|
||||||
|
struct StorageImageData {
|
||||||
|
QRhiTexture *tex;
|
||||||
|
int level;
|
||||||
|
};
|
||||||
|
struct StorageBufferData {
|
||||||
|
QRhiBuffer *buf;
|
||||||
|
int offset;
|
||||||
|
int maybeSize;
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
UniformBufferData ubuf;
|
||||||
|
SampledTextureData stex;
|
||||||
|
StorageImageData simage;
|
||||||
|
StorageBufferData sbuf;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
Data *data() { return &d; }
|
||||||
|
const Data *data() const { return &d; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QRhiShaderResourceBindingPrivate *d;
|
Data d;
|
||||||
friend class QRhiShaderResourceBindingPrivate;
|
|
||||||
friend Q_GUI_EXPORT bool operator==(const QRhiShaderResourceBinding &, const QRhiShaderResourceBinding &) Q_DECL_NOTHROW;
|
|
||||||
friend Q_GUI_EXPORT bool operator!=(const QRhiShaderResourceBinding &, const QRhiShaderResourceBinding &) Q_DECL_NOTHROW;
|
|
||||||
friend Q_GUI_EXPORT uint qHash(const QRhiShaderResourceBinding &, uint) Q_DECL_NOTHROW;
|
|
||||||
#ifndef QT_NO_DEBUG_STREAM
|
|
||||||
friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiShaderResourceBinding &);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiShaderResourceBinding::StageFlags)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(QRhiShaderResourceBinding::StageFlags)
|
||||||
|
|
||||||
|
Q_DECLARE_TYPEINFO(QRhiShaderResourceBinding, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
Q_GUI_EXPORT bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
|
Q_GUI_EXPORT bool operator==(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
|
||||||
Q_GUI_EXPORT bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
|
Q_GUI_EXPORT bool operator!=(const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b) Q_DECL_NOTHROW;
|
||||||
Q_GUI_EXPORT uint qHash(const QRhiShaderResourceBinding &b, uint seed = 0) Q_DECL_NOTHROW;
|
Q_GUI_EXPORT uint qHash(const QRhiShaderResourceBinding &b, uint seed = 0) Q_DECL_NOTHROW;
|
||||||
|
@ -381,57 +381,6 @@ Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate, Q_MOVABL
|
|||||||
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::StaticBufferUpload, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::StaticBufferUpload, Q_MOVABLE_TYPE);
|
||||||
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureOp, Q_MOVABLE_TYPE);
|
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureOp, Q_MOVABLE_TYPE);
|
||||||
|
|
||||||
class Q_GUI_EXPORT QRhiShaderResourceBindingPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QRhiShaderResourceBindingPrivate()
|
|
||||||
: ref(1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QRhiShaderResourceBindingPrivate(const QRhiShaderResourceBindingPrivate *other)
|
|
||||||
: ref(1),
|
|
||||||
binding(other->binding),
|
|
||||||
stage(other->stage),
|
|
||||||
type(other->type),
|
|
||||||
u(other->u)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static QRhiShaderResourceBindingPrivate *get(QRhiShaderResourceBinding *s) { return s->d; }
|
|
||||||
static const QRhiShaderResourceBindingPrivate *get(const QRhiShaderResourceBinding *s) { return s->d; }
|
|
||||||
|
|
||||||
QAtomicInt ref;
|
|
||||||
int binding;
|
|
||||||
QRhiShaderResourceBinding::StageFlags stage;
|
|
||||||
QRhiShaderResourceBinding::Type type;
|
|
||||||
struct UniformBufferData {
|
|
||||||
QRhiBuffer *buf;
|
|
||||||
int offset;
|
|
||||||
int maybeSize;
|
|
||||||
bool hasDynamicOffset;
|
|
||||||
};
|
|
||||||
struct SampledTextureData {
|
|
||||||
QRhiTexture *tex;
|
|
||||||
QRhiSampler *sampler;
|
|
||||||
};
|
|
||||||
struct StorageImageData {
|
|
||||||
QRhiTexture *tex;
|
|
||||||
int level;
|
|
||||||
};
|
|
||||||
struct StorageBufferData {
|
|
||||||
QRhiBuffer *buf;
|
|
||||||
int offset;
|
|
||||||
int maybeSize;
|
|
||||||
};
|
|
||||||
union {
|
|
||||||
UniformBufferData ubuf;
|
|
||||||
SampledTextureData stex;
|
|
||||||
StorageImageData simage;
|
|
||||||
StorageBufferData sbuf;
|
|
||||||
} u;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct QRhiBatchedBindings
|
struct QRhiBatchedBindings
|
||||||
{
|
{
|
||||||
|
@ -598,7 +598,7 @@ void QRhiD3D11::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
bool hasDynamicOffsetInSrb = false;
|
bool hasDynamicOffsetInSrb = false;
|
||||||
bool srbUpdate = false;
|
bool srbUpdate = false;
|
||||||
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
|
const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
|
||||||
QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
|
QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
@ -1746,7 +1746,7 @@ void QRhiD3D11::updateShaderResourceBindings(QD3D11ShaderResourceBindings *srbD)
|
|||||||
srbD->csUAVs.clear();
|
srbD->csUAVs.clear();
|
||||||
|
|
||||||
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
|
const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
|
||||||
QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
|
QD3D11ShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
@ -3086,7 +3086,7 @@ bool QD3D11ShaderResourceBindings::build()
|
|||||||
std::sort(sortedBindings.begin(), sortedBindings.end(),
|
std::sort(sortedBindings.begin(), sortedBindings.end(),
|
||||||
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
|
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
|
||||||
{
|
{
|
||||||
return QRhiShaderResourceBindingPrivate::get(&a)->binding < QRhiShaderResourceBindingPrivate::get(&b)->binding;
|
return a.data()->binding < b.data()->binding;
|
||||||
});
|
});
|
||||||
|
|
||||||
boundResourceData.resize(sortedBindings.count());
|
boundResourceData.resize(sortedBindings.count());
|
||||||
|
@ -868,7 +868,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb);
|
QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb);
|
||||||
bool hasDynamicOffsetInSrb = false;
|
bool hasDynamicOffsetInSrb = false;
|
||||||
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->m_bindings[i]);
|
const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data();
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
// no BufUniformRead / AccessUniform because no real uniform buffers are used
|
// no BufUniformRead / AccessUniform because no real uniform buffers are used
|
||||||
@ -2306,7 +2306,7 @@ void QRhiGles2::bindShaderResources(QRhiGraphicsPipeline *maybeGraphicsPs, QRhiC
|
|||||||
int texUnit = 0;
|
int texUnit = 0;
|
||||||
|
|
||||||
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->m_bindings[i]);
|
const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data();
|
||||||
|
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
|
@ -656,7 +656,7 @@ void QRhiMetal::enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD
|
|||||||
} res[KNOWN_STAGES];
|
} res[KNOWN_STAGES];
|
||||||
|
|
||||||
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
|
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
|
const QRhiShaderResourceBinding::Data *b = binding.data();
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
{
|
{
|
||||||
@ -875,7 +875,7 @@ void QRhiMetal::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
|
|
||||||
// do buffer writes, figure out if we need to rebind, and mark as in-use
|
// do buffer writes, figure out if we need to rebind, and mark as in-use
|
||||||
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
|
const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
|
||||||
QMetalShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
|
QMetalShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[i]);
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
@ -2772,17 +2772,17 @@ bool QMetalShaderResourceBindings::build()
|
|||||||
std::sort(sortedBindings.begin(), sortedBindings.end(),
|
std::sort(sortedBindings.begin(), sortedBindings.end(),
|
||||||
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
|
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
|
||||||
{
|
{
|
||||||
return QRhiShaderResourceBindingPrivate::get(&a)->binding < QRhiShaderResourceBindingPrivate::get(&b)->binding;
|
return a.data()->binding < b.data()->binding;
|
||||||
});
|
});
|
||||||
if (!sortedBindings.isEmpty())
|
if (!sortedBindings.isEmpty())
|
||||||
maxBinding = QRhiShaderResourceBindingPrivate::get(&sortedBindings.last())->binding;
|
maxBinding = sortedBindings.last().data()->binding;
|
||||||
else
|
else
|
||||||
maxBinding = -1;
|
maxBinding = -1;
|
||||||
|
|
||||||
boundResourceData.resize(sortedBindings.count());
|
boundResourceData.resize(sortedBindings.count());
|
||||||
|
|
||||||
for (int i = 0, ie = sortedBindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = sortedBindings.count(); i != ie; ++i) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&sortedBindings[i]);
|
const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
|
||||||
QMetalShaderResourceBindings::BoundResourceData &bd(boundResourceData[i]);
|
QMetalShaderResourceBindings::BoundResourceData &bd(boundResourceData[i]);
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
|
@ -2313,7 +2313,7 @@ void QRhiVulkan::updateShaderResourceBindings(QRhiShaderResourceBindings *srb, i
|
|||||||
while (frameSlot < (updateAll ? QVK_FRAMES_IN_FLIGHT : descSetIdx + 1)) {
|
while (frameSlot < (updateAll ? QVK_FRAMES_IN_FLIGHT : descSetIdx + 1)) {
|
||||||
srbD->boundResourceData[frameSlot].resize(srbD->sortedBindings.count());
|
srbD->boundResourceData[frameSlot].resize(srbD->sortedBindings.count());
|
||||||
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
|
const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
|
||||||
QVkShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[frameSlot][i]);
|
QVkShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[frameSlot][i]);
|
||||||
|
|
||||||
VkWriteDescriptorSet writeInfo;
|
VkWriteDescriptorSet writeInfo;
|
||||||
@ -3870,7 +3870,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
|
|||||||
bool hasDynamicOffsetInSrb = false;
|
bool hasDynamicOffsetInSrb = false;
|
||||||
|
|
||||||
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
|
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
|
const QRhiShaderResourceBinding::Data *b = binding.data();
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
if (QRHI_RES(QVkBuffer, b->u.ubuf.buf)->m_type == QRhiBuffer::Dynamic)
|
if (QRHI_RES(QVkBuffer, b->u.ubuf.buf)->m_type == QRhiBuffer::Dynamic)
|
||||||
@ -3889,7 +3889,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
|
|||||||
// Do host writes and mark referenced shader resources as in-use.
|
// Do host writes and mark referenced shader resources as in-use.
|
||||||
// Also prepare to ensure the descriptor set we are going to bind refers to up-to-date Vk objects.
|
// Also prepare to ensure the descriptor set we are going to bind refers to up-to-date Vk objects.
|
||||||
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
for (int i = 0, ie = srbD->sortedBindings.count(); i != ie; ++i) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&srbD->sortedBindings[i]);
|
const QRhiShaderResourceBinding::Data *b = srbD->sortedBindings.at(i).data();
|
||||||
QVkShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[descSetIdx][i]);
|
QVkShaderResourceBindings::BoundResourceData &bd(srbD->boundResourceData[descSetIdx][i]);
|
||||||
QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);
|
QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
@ -4022,7 +4022,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
|
|||||||
// and neither srb nor dynamicOffsets has any such ordering
|
// and neither srb nor dynamicOffsets has any such ordering
|
||||||
// requirement.
|
// requirement.
|
||||||
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
|
for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
|
const QRhiShaderResourceBinding::Data *b = binding.data();
|
||||||
if (b->type == QRhiShaderResourceBinding::UniformBuffer && b->u.ubuf.hasDynamicOffset) {
|
if (b->type == QRhiShaderResourceBinding::UniformBuffer && b->u.ubuf.hasDynamicOffset) {
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
for (int i = 0; i < dynamicOffsetCount; ++i) {
|
||||||
@ -4750,7 +4750,7 @@ static inline void fillVkStencilOpState(VkStencilOpState *dst, const QRhiGraphic
|
|||||||
dst->compareOp = toVkCompareOp(src.compareOp);
|
dst->compareOp = toVkCompareOp(src.compareOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline VkDescriptorType toVkDescriptorType(const QRhiShaderResourceBindingPrivate *b)
|
static inline VkDescriptorType toVkDescriptorType(const QRhiShaderResourceBinding::Data *b)
|
||||||
{
|
{
|
||||||
switch (b->type) {
|
switch (b->type) {
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
@ -5701,12 +5701,12 @@ bool QVkShaderResourceBindings::build()
|
|||||||
std::sort(sortedBindings.begin(), sortedBindings.end(),
|
std::sort(sortedBindings.begin(), sortedBindings.end(),
|
||||||
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
|
[](const QRhiShaderResourceBinding &a, const QRhiShaderResourceBinding &b)
|
||||||
{
|
{
|
||||||
return QRhiShaderResourceBindingPrivate::get(&a)->binding < QRhiShaderResourceBindingPrivate::get(&b)->binding;
|
return a.data()->binding < b.data()->binding;
|
||||||
});
|
});
|
||||||
|
|
||||||
QVarLengthArray<VkDescriptorSetLayoutBinding, 4> vkbindings;
|
QVarLengthArray<VkDescriptorSetLayoutBinding, 4> vkbindings;
|
||||||
for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) {
|
for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) {
|
||||||
const QRhiShaderResourceBindingPrivate *b = QRhiShaderResourceBindingPrivate::get(&binding);
|
const QRhiShaderResourceBinding::Data *b = binding.data();
|
||||||
VkDescriptorSetLayoutBinding vkbinding;
|
VkDescriptorSetLayoutBinding vkbinding;
|
||||||
memset(&vkbinding, 0, sizeof(vkbinding));
|
memset(&vkbinding, 0, sizeof(vkbinding));
|
||||||
vkbinding.binding = uint32_t(b->binding);
|
vkbinding.binding = uint32_t(b->binding);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user