diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2022-10-31 14:35:37 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2022-11-01 20:32:28 +0100 |
commit | 46bd6cd051d8a56c3a0da0ec6793a78eaf4d31fe (patch) | |
tree | 941184a5fe9eb3b2564a8dd89ab44201ca3bfda4 /src/gui/rhi/qrhimetal.mm | |
parent | eb5f33c7a18f93002f64948a1c78b32fc678a5af (diff) |
rhi: metal: Do not rely on registry id for cache keys
This is apparently not suitable: the MTLDevice's registryID is stable
across processes and allows identifying a device (GPU), but the
value may apparently change when the system is rebooted. We see this
both in the CI's M1s and also locally. There may also be differences
between Intel or discreet graphics vs. Apple Silicon based machines
but that we won't be able to investigate further.
Inspired by MoltenVK, stop using the registryID as our "device id",
and instead store the OS version in the cache header. Combined with
the device name this should be good enough.
To generate a device/vendor ID, that we give up for now, those will
be 0 in the QRhiDriverInfo like they are for OpenGL.
This should prevent the "Metal device ID does not match" warnings
that tend to pop up in CI logs and elsewhere. (it also improves
performance, obviously since there is no reason we could not
reuse the disk cache on the same machine where nothing really
has changed, and now we will not incorrectly throw away the
previously written cache contents)
Change-Id: Ib457f6671aceb51f5a9d241702b418aafc888e51
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi/qrhimetal.mm')
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 35 |
1 files changed, 18 insertions, 17 deletions
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 5b18ff3e96..83f245c9ac 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -10,6 +10,7 @@ #include <QTemporaryFile> #include <QFileInfo> #include <qmath.h> +#include <QOperatingSystemVersion> #include <QtCore/private/qcore_mac_p.h> @@ -476,7 +477,11 @@ bool QRhiMetal::create(QRhi::Flags flags) const QString deviceName = QString::fromNSString([d->dev name]); qCDebug(QRHI_LOG_INFO, "Metal device: %s", qPrintable(deviceName)); driverInfoStruct.deviceName = deviceName.toUtf8(); - driverInfoStruct.deviceId = [d->dev registryID]; + + // deviceId and vendorId stay unset for now. Note that registryID is not + // suitable as deviceId because it does not seem stable on macOS and can + // apparently change when the system is rebooted. + #ifdef Q_OS_IOS driverInfoStruct.deviceType = QRhiDriverInfo::IntegratedDevice; #else @@ -498,6 +503,10 @@ bool QRhiMetal::create(QRhi::Flags flags) } #endif + const QOperatingSystemVersion ver = QOperatingSystemVersion::current(); + osMajor = ver.majorVersion(); + osMinor = ver.minorVersion(); + if (importedCmdQueue) [d->cmdQueue retain]; else @@ -844,10 +853,9 @@ struct QMetalPipelineCacheDataHeader quint32 rhiId; quint32 arch; quint32 dataSize; - quint32 reserved; - quint64 deviceId; - quint64 vendorId; - char driver[224]; + quint32 osMajor; + quint32 osMinor; + char driver[236]; }; QByteArray QRhiMetal::pipelineCacheData() @@ -891,9 +899,8 @@ QByteArray QRhiMetal::pipelineCacheData() header.rhiId = pipelineCacheRhiId(); header.arch = quint32(sizeof(void*)); header.dataSize = quint32(dataSize); - header.deviceId = driverInfoStruct.deviceId; - header.vendorId = driverInfoStruct.vendorId; - + header.osMajor = osMajor; + header.osMinor = osMinor; const size_t driverStrLen = qMin(sizeof(header.driver) - 1, size_t(driverInfoStruct.deviceName.length())); if (driverStrLen) memcpy(header.driver, driverInfoStruct.deviceName.constData(), driverStrLen); @@ -934,15 +941,9 @@ void QRhiMetal::setPipelineCacheData(const QByteArray &data) return; } - if (header.deviceId != driverInfoStruct.deviceId) { - qWarning("setPipelineCacheData: Metal device ID does not match (%llu, %llu)", - driverInfoStruct.deviceId, header.deviceId); - return; - } - - if (header.vendorId != driverInfoStruct.vendorId) { - qWarning("setPipelineCacheData: Metal vendor ID does not match (%llu, %llu)", - driverInfoStruct.vendorId, header.vendorId); + if (header.osMajor != osMajor || header.osMinor != osMinor) { + qWarning("setPipelineCacheData: OS version does not match (%u.%u, %u.%u)", + osMajor, osMinor, header.osMajor, header.osMinor); return; } |