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 6.7
Change-Id: I6398f4f27d00950c7dceae918b04e0054d4b5647
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
bb10
Philip Schuchardt 2023-11-25 21:44:19 -06:00 committed by Laszlo Agocs
parent ee8822168c
commit f21af7f88b
1 changed files with 16 additions and 9 deletions

View File

@ -2682,6 +2682,15 @@ void QRhiMetal::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
QMetalCommandBuffer *cbD = QRHI_RES(QMetalCommandBuffer, cb);
QRhiResourceUpdateBatchPrivate *ud = QRhiResourceUpdateBatchPrivate::get(resourceUpdates);
id<MTLBlitCommandEncoder> 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<MTLBlitCommandEncoder> 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) {