summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/rhi/qrhi.cpp110
-rw-r--r--src/gui/rhi/qrhi_p_p.h20
-rw-r--r--src/gui/rhi/qrhid3d11.cpp7
-rw-r--r--src/gui/rhi/qrhigles2.cpp6
-rw-r--r--src/gui/rhi/qrhimetal.mm6
-rw-r--r--src/gui/rhi/qrhinull.cpp6
-rw-r--r--src/gui/rhi/qrhivulkan.cpp6
7 files changed, 125 insertions, 36 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index a74765758c..849519cb7a 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -4694,8 +4694,9 @@ void QRhiResourceUpdateBatch::release()
/*!
Copies all queued operations from the \a other batch into this one.
- \note \a other is not changed in any way, typically it will still need a
- destroy()
+ \note \a other may no longer contain valid data after the merge operation,
+ and must not be submitted, but it will still need to be released by calling
+ release().
This allows for a convenient pattern where resource updates that are
already known during the initialization step are collected into a batch
@@ -4718,7 +4719,7 @@ void QRhiResourceUpdateBatch::release()
QRhiResourceUpdateBatch *resUpdates = rhi->nextResourceUpdateBatch();
if (initialUpdates) {
resUpdates->merge(initialUpdates);
- initialUpdates->destroy();
+ initialUpdates->release();
initialUpdates = nullptr;
}
resUpdates->updateDynamicBuffer(...);
@@ -4771,8 +4772,14 @@ bool QRhiResourceUpdateBatch::hasOptimalCapacity() const
*/
void QRhiResourceUpdateBatch::updateDynamicBuffer(QRhiBuffer *buf, int offset, int size, const void *data)
{
- if (size > 0)
- d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::dynamicUpdate(buf, offset, size, data));
+ if (size > 0) {
+ const int idx = d->activeBufferOpCount++;
+ const int opListSize = d->bufferOps.size();
+ if (idx < opListSize)
+ QRhiResourceUpdateBatchPrivate::BufferOp::changeToDynamicUpdate(&d->bufferOps[idx], buf, offset, size, data);
+ else
+ d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::dynamicUpdate(buf, offset, size, data));
+ }
}
/*!
@@ -4785,8 +4792,13 @@ void QRhiResourceUpdateBatch::updateDynamicBuffer(QRhiBuffer *buf, int offset, i
*/
void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, int offset, int size, const void *data)
{
- if (size > 0)
- d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::staticUpload(buf, offset, size, data));
+ if (size > 0) {
+ const int idx = d->activeBufferOpCount++;
+ if (idx < d->bufferOps.size())
+ QRhiResourceUpdateBatchPrivate::BufferOp::changeToStaticUpload(&d->bufferOps[idx], buf, offset, size, data);
+ else
+ d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::staticUpload(buf, offset, size, data));
+ }
}
/*!
@@ -4795,8 +4807,13 @@ void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, int offset, in
*/
void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *data)
{
- if (buf->size() > 0)
- d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::staticUpload(buf, 0, 0, data));
+ if (buf->size() > 0) {
+ const int idx = d->activeBufferOpCount++;
+ if (idx < d->bufferOps.size())
+ QRhiResourceUpdateBatchPrivate::BufferOp::changeToStaticUpload(&d->bufferOps[idx], buf, 0, 0, data);
+ else
+ d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::staticUpload(buf, 0, 0, data));
+ }
}
/*!
@@ -4825,7 +4842,11 @@ void QRhiResourceUpdateBatch::uploadStaticBuffer(QRhiBuffer *buf, const void *da
*/
void QRhiResourceUpdateBatch::readBackBuffer(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result)
{
- d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::read(buf, offset, size, result));
+ const int idx = d->activeBufferOpCount++;
+ if (idx < d->bufferOps.size())
+ d->bufferOps[idx] = QRhiResourceUpdateBatchPrivate::BufferOp::read(buf, offset, size, result);
+ else
+ d->bufferOps.append(QRhiResourceUpdateBatchPrivate::BufferOp::read(buf, offset, size, result));
}
/*!
@@ -4837,8 +4858,13 @@ void QRhiResourceUpdateBatch::readBackBuffer(QRhiBuffer *buf, int offset, int si
*/
void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
{
- if (desc.cbeginEntries() != desc.cendEntries())
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::upload(tex, desc));
+ if (desc.cbeginEntries() != desc.cendEntries()) {
+ const int idx = d->activeTextureOpCount++;
+ if (idx < d->textureOps.size())
+ d->textureOps[idx] = QRhiResourceUpdateBatchPrivate::TextureOp::upload(tex, desc);
+ else
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::upload(tex, desc));
+ }
}
/*!
@@ -4863,7 +4889,11 @@ void QRhiResourceUpdateBatch::uploadTexture(QRhiTexture *tex, const QImage &imag
*/
void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc)
{
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::copy(dst, src, desc));
+ const int idx = d->activeTextureOpCount++;
+ if (idx < d->textureOps.size())
+ d->textureOps[idx] = QRhiResourceUpdateBatchPrivate::TextureOp::copy(dst, src, desc);
+ else
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::copy(dst, src, desc));
}
/*!
@@ -4925,7 +4955,11 @@ void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, co
*/
void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::read(rb, result));
+ const int idx = d->activeTextureOpCount++;
+ if (idx < d->textureOps.size())
+ d->textureOps[idx] = QRhiResourceUpdateBatchPrivate::TextureOp::read(rb, result);
+ else
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::read(rb, result));
}
/*!
@@ -4937,7 +4971,11 @@ void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb,
*/
void QRhiResourceUpdateBatch::generateMips(QRhiTexture *tex, int layer)
{
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::genMips(tex, layer));
+ const int idx = d->activeTextureOpCount++;
+ if (idx < d->textureOps.size())
+ d->textureOps[idx] = QRhiResourceUpdateBatchPrivate::TextureOp::genMips(tex, layer);
+ else
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::genMips(tex, layer));
}
/*!
@@ -4997,8 +5035,8 @@ void QRhiResourceUpdateBatchPrivate::free()
{
Q_ASSERT(poolIndex >= 0 && rhi->resUpdPool[poolIndex] == q);
- bufferOps.clear();
- textureOps.clear();
+ activeBufferOpCount = 0;
+ activeTextureOpCount = 0;
rhi->resUpdPoolMap.clearBit(poolIndex);
poolIndex = -1;
@@ -5006,19 +5044,36 @@ void QRhiResourceUpdateBatchPrivate::free()
void QRhiResourceUpdateBatchPrivate::merge(QRhiResourceUpdateBatchPrivate *other)
{
- bufferOps.reserve(bufferOps.size() + other->bufferOps.size());
- for (const BufferOp &op : qAsConst(other->bufferOps))
- bufferOps.append(op);
+ int combinedSize = activeBufferOpCount + other->activeBufferOpCount;
+ if (bufferOps.size() < combinedSize)
+ bufferOps.resize(combinedSize);
+ for (int i = activeBufferOpCount; i < combinedSize; ++i)
+ bufferOps[i] = std::move(other->bufferOps[i - activeBufferOpCount]);
+ activeBufferOpCount += other->activeBufferOpCount;
- textureOps.reserve(textureOps.size() + other->textureOps.size());
- for (const TextureOp &op : qAsConst(other->textureOps))
- textureOps.append(op);
+ combinedSize = activeTextureOpCount + other->activeTextureOpCount;
+ if (textureOps.size() < combinedSize)
+ textureOps.resize(combinedSize);
+ for (int i = activeTextureOpCount; i < combinedSize; ++i)
+ textureOps[i] = std::move(other->textureOps[i - activeTextureOpCount]);
+ activeTextureOpCount += other->activeTextureOpCount;
}
bool QRhiResourceUpdateBatchPrivate::hasOptimalCapacity() const
{
- return bufferOps.count() < BUFFER_OPS_STATIC_ALLOC - 16
- && textureOps.count() < TEXTURE_OPS_STATIC_ALLOC - 16;
+ return activeBufferOpCount < BUFFER_OPS_STATIC_ALLOC - 16
+ && activeTextureOpCount < TEXTURE_OPS_STATIC_ALLOC - 16;
+}
+
+void QRhiResourceUpdateBatchPrivate::trimOpLists()
+{
+ Q_ASSERT(poolIndex == -1); // must not be in use
+
+ activeBufferOpCount = 0;
+ bufferOps.clear();
+
+ activeTextureOpCount = 0;
+ textureOps.clear();
}
/*!
@@ -5723,6 +5778,11 @@ QRhiProfiler *QRhi::profiler()
void QRhi::releaseCachedResources()
{
d->releaseCachedResources();
+
+ for (QRhiResourceUpdateBatch *u : d->resUpdPool) {
+ if (u->d->poolIndex < 0)
+ u->d->trimOpLists();
+ }
}
/*!
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 7fadcfcc1e..a7d8a40bf9 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -302,6 +302,14 @@ public:
return op;
}
+ static void changeToDynamicUpdate(BufferOp *op, QRhiBuffer *buf, int offset, int size, const void *data)
+ {
+ op->type = DynamicUpdate;
+ op->buf = buf;
+ op->offset = offset;
+ op->data = QByteArray(reinterpret_cast<const char *>(data), size ? size : buf->size());
+ }
+
static BufferOp staticUpload(QRhiBuffer *buf, int offset, int size, const void *data)
{
BufferOp op = {};
@@ -312,6 +320,14 @@ public:
return op;
}
+ static void changeToStaticUpload(BufferOp *op, QRhiBuffer *buf, int offset, int size, const void *data)
+ {
+ op->type = StaticUpload;
+ op->buf = buf;
+ op->offset = offset;
+ op->data = QByteArray(reinterpret_cast<const char *>(data), size ? size : buf->size());
+ }
+
static BufferOp read(QRhiBuffer *buf, int offset, int size, QRhiBufferReadbackResult *result)
{
BufferOp op = {};
@@ -383,8 +399,11 @@ public:
}
};
+ int activeBufferOpCount = 0; // this is the real number of used elements in bufferOps, not bufferOps.count()
static const int BUFFER_OPS_STATIC_ALLOC = 1024;
QVarLengthArray<BufferOp, BUFFER_OPS_STATIC_ALLOC> bufferOps;
+
+ int activeTextureOpCount = 0; // this is the real number of used elements in textureOps, not textureOps.count()
static const int TEXTURE_OPS_STATIC_ALLOC = 256;
QVarLengthArray<TextureOp, TEXTURE_OPS_STATIC_ALLOC> textureOps;
@@ -395,6 +414,7 @@ public:
void free();
void merge(QRhiResourceUpdateBatchPrivate *other);
bool hasOptimalCapacity() const;
+ void trimOpLists();
static QRhiResourceUpdateBatchPrivate *get(QRhiResourceUpdateBatch *b) { return b->d; }
};
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index f3ddc7aac4..3b14b77ce1 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -1413,7 +1413,8 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ for (int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::BufferOp &u(ud->bufferOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
QD3D11Buffer *bufD = QRHI_RES(QD3D11Buffer, u.buf);
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
@@ -1485,8 +1486,8 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
u.result->completed();
}
}
-
- for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
+ for (int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
QD3D11Texture *texD = QRHI_RES(QD3D11Texture, u.dst);
for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 39c01b1144..190d506f9a 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -1681,7 +1681,8 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
- for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ for (int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::BufferOp &u(ud->bufferOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, u.buf);
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
@@ -1735,7 +1736,8 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
}
}
- for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
+ for (int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
QGles2Texture *texD = QRHI_RES(QGles2Texture, u.dst);
for (int layer = 0; layer < QRhi::MAX_LAYERS; ++layer) {
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index a770c72a99..55adaa4d54 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -1691,7 +1691,8 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ for (int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::BufferOp &u(ud->bufferOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
QMetalBuffer *bufD = QRHI_RES(QMetalBuffer, u.buf);
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
@@ -1729,7 +1730,8 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
}
};
- for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
+ for (int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
QMetalTexture *utexD = QRHI_RES(QMetalTexture, u.dst);
qsizetype stagingSize = 0;
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index 48fca4e212..94d24c33a9 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -459,7 +459,8 @@ void QRhiNull::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *re
{
Q_UNUSED(cb);
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
- for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ for (int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::BufferOp &u(ud->bufferOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate
|| u.type == QRhiResourceUpdateBatchPrivate::BufferOp::StaticUpload)
{
@@ -474,7 +475,8 @@ void QRhiNull::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *re
result->completed();
}
}
- for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
+ for (int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
if (u.dst->format() == QRhiTexture::RGBA8)
simulateTextureUpload(u);
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 64609671ab..9ac8ef70ee 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -2923,7 +2923,8 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
- for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : ud->bufferOps) {
+ for (int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::BufferOp &u(ud->bufferOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) {
QVkBuffer *bufD = QRHI_RES(QVkBuffer, u.buf);
Q_ASSERT(bufD->m_type == QRhiBuffer::Dynamic);
@@ -3073,7 +3074,8 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
}
}
- for (const QRhiResourceUpdateBatchPrivate::TextureOp &u : ud->textureOps) {
+ for (int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) {
+ const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]);
if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {
QVkTexture *utexD = QRHI_RES(QVkTexture, u.dst);
// batch into a single staging buffer and a single CopyBufferToImage with multiple copyInfos