summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/rhi/qrhi.cpp')
-rw-r--r--src/gui/rhi/qrhi.cpp110
1 files changed, 85 insertions, 25 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();
+ }
}
/*!