From 86cdd53a6d69070ff26edb6d10e8f2097a430a59 Mon Sep 17 00:00:00 2001 From: Philip Schuchardt Date: Sat, 25 Nov 2023 21:44:19 -0600 Subject: [PATCH] Synchronize read buffers on non-Apple Silicon in RHI Read buffers are not automatically synchronized when the buffer uses MTLResourceStorageModeManaged. This commit adds GPU to CPU synchronization for managed buffers, ensuring proper data transfer for reading operations on non-Apple Silicon devices. Fixes: QTBUG-119447 Pick-to: 6.6 Change-Id: I6398f4f27d00950c7dceae918b04e0054d4b5647 Reviewed-by: Laszlo Agocs Reviewed-by: Qt CI Bot (cherry picked from commit f21af7f88b2184a420293967d07bf6552541ddc9) Reviewed-by: Qt Cherry-pick Bot --- src/gui/rhi/qrhimetal.mm | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 56bb4815b93..e02ab9a2780 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -2682,6 +2682,15 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb); QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates); + id blitEnc = nil; + auto ensureBlit = [&blitEnc, cbD, this]() { + if (!blitEnc) { + blitEnc = [cbD->d->cb blitCommandEncoder]; + if (debugMarkers) + [blitEnc pushDebugGroup: @"Texture upload/copy"]; + } + }; + for (int opIdx = 0; opIdx < ud->activeBufferOpCount; ++opIdx) { const QRhiResourceUpdateBatchPrivate::BufferOp &u(ud->bufferOps[opIdx]); if (u.type == QRhiResourceUpdateBatchPrivate::BufferOp::DynamicUpdate) { @@ -2720,19 +2729,17 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate readback.readSize = u.readSize; readback.result = u.result; d->activeBufferReadbacks.append(readback); +#ifdef Q_OS_MACOS + if (bufD->d->managed) { + // On non-Apple Silicon, manually synchronize memory from GPU to CPU + ensureBlit(); + [blitEnc synchronizeResource:readback.buf]; + } +#endif } } } - id blitEnc = nil; - auto ensureBlit = [&blitEnc, cbD, this] { - if (!blitEnc) { - blitEnc = [cbD->d->cb blitCommandEncoder]; - if (debugMarkers) - [blitEnc pushDebugGroup: @"Texture upload/copy"]; - } - }; - for (int opIdx = 0; opIdx < ud->activeTextureOpCount; ++opIdx) { const QRhiResourceUpdateBatchPrivate::TextureOp &u(ud->textureOps[opIdx]); if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::Upload) {