diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/rhi/qrhi.cpp | 48 | ||||
-rw-r--r-- | src/gui/rhi/qrhi_p.h | 1 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 11 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal_p_p.h | 2 |
4 files changed, 62 insertions, 0 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp index 6058dd3a55..d62b2eea61 100644 --- a/src/gui/rhi/qrhi.cpp +++ b/src/gui/rhi/qrhi.cpp @@ -5288,6 +5288,20 @@ QRhi::~QRhi() subclasses of QRhiInitParams, such as, QRhiVulkanInitParams, QRhiMetalInitParams, QRhiD3D11InitParams, QRhiGles2InitParams. See these classes for examples on creating a QRhi. + + QRhi by design does not implement any fallback logic: if the specified API + cannot be initialized, create() will fail, with warnings printed on the + debug output by the backends. The clients of QRhi, for example Qt Quick, + may however provide additional logic that allow falling back to an API + different than what was requested, depending on the platform. If the + intention is just to test if initialization would succeed when calling + create() at later point, it is preferable to use probe() instead of + create(), because with some backends probing can be implemented in a more + lightweight manner as opposed to create(), which performs full + initialization of the infrastructure and is wasteful if that QRhi instance + is then thrown immediately away. + + \sa probe() */ QRhi *QRhi::create(Implementation impl, QRhiInitParams *params, Flags flags, QRhiNativeHandles *importDevice) { @@ -5358,6 +5372,40 @@ QRhi *QRhi::create(Implementation impl, QRhiInitParams *params, Flags flags, QRh } /*! + \return true if create() can be expected to succeed when called the given + \a impl and \a params. + + For some backends this is equivalent to calling create(), checking its + return value, and then destroying the resulting QRhi. + + For others, in particular with Metal, there may be a specific probing + implementation, which allows testing in a more lightweight manner without + polluting the debug output with warnings upon failures. + + \sa create() + */ +bool QRhi::probe(QRhi::Implementation impl, QRhiInitParams *params) +{ + bool ok = false; + + // The only place currently where this makes sense is Metal, where the API + // is simple enough so that a special probing function - doing nothing but + // a MTLCreateSystemDefaultDevice - is reasonable. Elsewhere, just call + // create() and then drop the result. + + if (impl == Metal) { +#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) + ok = QRhiMetal::probe(static_cast<QRhiMetalInitParams *>(params)); +#endif + } else { + QRhi *rhi = create(impl, params); + ok = rhi != nullptr; + delete rhi; + } + return ok; +} + +/*! \return the backend type for this QRhi. */ QRhi::Implementation QRhi::backend() const diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h index 972aed6fd8..c96b773e0b 100644 --- a/src/gui/rhi/qrhi_p.h +++ b/src/gui/rhi/qrhi_p.h @@ -1711,6 +1711,7 @@ public: QRhiInitParams *params, Flags flags = {}, QRhiNativeHandles *importDevice = nullptr); + static bool probe(Implementation impl, QRhiInitParams *params); Implementation backend() const; const char *backendName() const; diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 3d53e8ab2d..c9cfb80d36 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -363,6 +363,17 @@ inline Int aligned(Int v, Int byteAlign) return (v + byteAlign - 1) & ~(byteAlign - 1); } +bool QRhiMetal::probe(QRhiMetalInitParams *params) +{ + Q_UNUSED(params); + id<MTLDevice> dev = MTLCreateSystemDefaultDevice(); + if (dev) { + [dev release]; + return true; + } + return false; +} + bool QRhiMetal::create(QRhi::Flags flags) { Q_UNUSED(flags); diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h index 5234a152e1..f96ddbe209 100644 --- a/src/gui/rhi/qrhimetal_p_p.h +++ b/src/gui/rhi/qrhimetal_p_p.h @@ -351,6 +351,8 @@ public: QRhiMetal(QRhiMetalInitParams *params, QRhiMetalNativeHandles *importDevice = nullptr); ~QRhiMetal(); + static bool probe(QRhiMetalInitParams *params); + bool create(QRhi::Flags flags) override; void destroy() override; |