diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 110 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p_p.h | 20 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d11.cpp | 7 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhinull.cpp | 6 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 6 |
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 |