summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhimetal.mm
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-02-23 15:05:44 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-03-03 18:25:56 +0100
commit753e4d82be966b82ff6ba41a0e7c4452f494790a (patch)
tree2c5a6ef94dc9bf29cb2ff972d707190850ee572a /src/gui/rhi/qrhimetal.mm
parent7b8616859adcb0c8b38591b0e9c1165c986bad92 (diff)
rhi: Execute pending host writes on nativeBuffer() query
Otherwise it is impossible to write an application that pulls out the VkBuffer for a Dynamic QRhiBuffer, and then uses it with custom Vulkan operations that read from the buffer. More precisely, the problem arises only if the buffer in question is not used in combination with any QRhi operations, because in that case there is nothing that would trigger doing the host writes queued up by a resource batch's updateDynamicBuffer(). Task-number: QTBUG-82435 Change-Id: Ieb54422f1493921bc6d4d029be56130cd3a1362a Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhimetal.mm')
-rw-r--r--src/gui/rhi/qrhimetal.mm23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 48a562ef1d..314c58b0b7 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -1827,16 +1827,15 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
}
// this handles all types of buffers, not just Dynamic
-void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
+void QRhiMetal::executeBufferHostWritesForSlot(QMetalBuffer *bufD, int slot)
{
- const int idx = bufD->d->slotted ? currentFrameSlot : 0;
- if (bufD->d->pendingUpdates[idx].isEmpty())
+ if (bufD->d->pendingUpdates[slot].isEmpty())
return;
- void *p = [bufD->d->buf[idx] contents];
+ void *p = [bufD->d->buf[slot] contents];
int changeBegin = -1;
int changeEnd = -1;
- for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : qAsConst(bufD->d->pendingUpdates[idx])) {
+ for (const QRhiResourceUpdateBatchPrivate::BufferOp &u : qAsConst(bufD->d->pendingUpdates[slot])) {
Q_ASSERT(bufD == QRHI_RES(QMetalBuffer, u.buf));
memcpy(static_cast<char *>(p) + u.offset, u.data.constData(), size_t(u.data.size()));
if (changeBegin == -1 || u.offset < changeBegin)
@@ -1846,10 +1845,15 @@ void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
}
#ifdef Q_OS_MACOS
if (changeBegin >= 0 && bufD->d->managed)
- [bufD->d->buf[idx] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))];
+ [bufD->d->buf[slot] didModifyRange: NSMakeRange(NSUInteger(changeBegin), NSUInteger(changeEnd - changeBegin))];
#endif
- bufD->d->pendingUpdates[idx].clear();
+ bufD->d->pendingUpdates[slot].clear();
+}
+
+void QRhiMetal::executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD)
+{
+ executeBufferHostWritesForSlot(bufD, bufD->d->slotted ? currentFrameSlot : 0);
}
void QRhiMetal::resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates)
@@ -2205,8 +2209,11 @@ QRhiBuffer::NativeBuffer QMetalBuffer::nativeBuffer()
if (d->slotted) {
NativeBuffer b;
Q_ASSERT(sizeof(b.objects) / sizeof(b.objects[0]) >= size_t(QMTL_FRAMES_IN_FLIGHT));
- for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i)
+ for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i) {
+ QRHI_RES_RHI(QRhiMetal);
+ rhiD->executeBufferHostWritesForSlot(this, i);
b.objects[i] = &d->buf[i];
+ }
b.slotCount = QMTL_FRAMES_IN_FLIGHT;
return b;
}