From 514ae9764008dafddd3022ef73f63ba8b2d7f430 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 8 Nov 2022 14:59:50 +0100 Subject: rhi: metal: Move macOS 13 pipeline cache workaround to the backend To allow removing the MACOS && IOS ifdefs from Qt Quick. The check is taken care of by the QRhi Metal backend instead. The logic is now slightly more sophisticated than just outright skipping the whole feature: we know that the problems (crash on M1/M2, and suspicious, constant blob size increases also on Macs with Intel graphics once upgraded to macOS 13) are triggered when new render/compute pipelines are registered to a MTLBinaryArchive that already loaded some data from a file serialized in a previous run of the application. Therefore, we just skip registering new pipelines when we believe it is not going to be safe. The rest of the persistent pipeline cache support is left intact and operates normally. Task-number: QTBUG-106703 Task-number: QTBUG-108216 Change-Id: Id3cc931dfbd940a3e6820ee9294459e4993e9ca7 Reviewed-by: Andy Nichols --- src/gui/rhi/qrhimetal.mm | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src/gui') diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 83f245c9ac..61b12ad46d 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -127,11 +127,13 @@ struct QMetalShader struct QRhiMetalData { - QRhiMetalData(QRhiImplementation *rhi) : ofr(rhi) { } + QRhiMetalData(QRhiMetal *rhi) : q(rhi), ofr(rhi) { } + QRhiMetal *q; id dev = nil; id cmdQueue = nil; API_AVAILABLE(macosx(11.0), ios(14.0)) id binArch = nil; + bool binArchWasEmpty = false; MTLRenderPassDescriptor *createDefaultRenderPass(bool hasDepthStencil, const QColor &colorClearValue, @@ -455,6 +457,7 @@ bool QRhiMetalData::setupBinaryArchive(NSURL *sourceFileUrl) qWarning("newBinaryArchiveWithDescriptor failed: %s", qPrintable(msg)); return false; } + binArchWasEmpty = sourceFileUrl == nil; return true; } return false; @@ -4485,10 +4488,33 @@ void QRhiMetalData::trySeedingRenderPipelineFromBinaryArchive(MTLRenderPipelineD } } +static bool canAddToBinaryArchive(QRhiMetalData *d) +{ + if (@available(macOS 11.0, iOS 14.0, *)) { + if (!d->binArch) + return false; + + // ### QTBUG-106703, QTBUG-108216, revisit after 13.0 + if (!d->binArchWasEmpty && d->q->osMajor >= 13) { + static bool logPrinted = false; + if (!logPrinted) { + logPrinted = true; + qCDebug(QRHI_LOG_INFO, "Skipping adding more pipelines to MTLBinaryArchive on this OS version (%d.%d) due to known issues.", + d->q->osMajor, d->q->osMinor); + } + return false; + } + + return true; + } else { + return false; + } +} + void QRhiMetalData::addRenderPipelineToBinaryArchive(MTLRenderPipelineDescriptor *rpDesc) { if (@available(macOS 11.0, iOS 14.0, *)) { - if (binArch) { + if (canAddToBinaryArchive(this)) { NSError *err = nil; if (![binArch addRenderPipelineFunctionsWithDescriptor: rpDesc error: &err]) { const QString msg = QString::fromNSString(err.localizedDescription); @@ -5211,7 +5237,7 @@ void QRhiMetalData::trySeedingComputePipelineFromBinaryArchive(MTLComputePipelin void QRhiMetalData::addComputePipelineToBinaryArchive(MTLComputePipelineDescriptor *cpDesc) { if (@available(macOS 11.0, iOS 14.0, *)) { - if (binArch) { + if (canAddToBinaryArchive(this)) { NSError *err = nil; if (![binArch addComputePipelineFunctionsWithDescriptor: cpDesc error: &err]) { const QString msg = QString::fromNSString(err.localizedDescription); -- cgit v1.2.3