summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhimetal.mm
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2022-10-31 14:35:37 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2022-11-01 20:32:28 +0100
commit46bd6cd051d8a56c3a0da0ec6793a78eaf4d31fe (patch)
tree941184a5fe9eb3b2564a8dd89ab44201ca3bfda4 /src/gui/rhi/qrhimetal.mm
parenteb5f33c7a18f93002f64948a1c78b32fc678a5af (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.mm35
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;
}