summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-08-13 18:13:43 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-08-18 21:42:49 +0000
commit88373a370ad12c8f81ee3497c5d1d87e70f446ee (patch)
treef22558952fcbe91afd17cad349870ac06bfb668e
parentc9c545eb4c48b28e81eaeb9a7e31fbd1fb246ddb (diff)
rhi: metal: Make base vertex and instance support optional
Like we do for OpenGL. Conveniently enough the QRhi feature flags are readily available. This should prevent errors such as: MTLValidateFeatureSupport:3901: failed assertion `Base Vertex Instance Drawing is not supported on this device' on the iOS Simulator. It is not clear since which version or SDK this became a fatal problem, but the base vertex/instance support is indeed an optional feature according to the Metal Feature set tables, so not calling the drawIndexedPrimitives variant taking baseVertex and baseInstance when the reported iOS GPU family is too low is the right thing to do regardless. Fixes: QTBUG-95795 Change-Id: I47c54a77a66a0410b86b8d4e5a1863dc730490f4 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> Reviewed-by: Andy Nichols <andy.nichols@qt.io> (cherry picked from commit 213755a86622ae8b3ed3d7ad34a6aecd051b2b03) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/gui/rhi/qrhi.cpp13
-rw-r--r--src/gui/rhi/qrhimetal.mm34
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h1
3 files changed, 34 insertions, 14 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index db85730040..5f841dde68 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -574,13 +574,18 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
require the point size to be set in the shader explicitly whenever drawing
points, even when the size is 1, as they do not automatically default to 1.
- \value BaseVertex Indicates that \l{QRhiCommandBuffer::drawIndexed()}{drawIndexed()}
- supports the \c vertexOffset argument. When reported as not supported, the
- vertexOffset value in an indexed draw is ignored.
+ \value BaseVertex Indicates that
+ \l{QRhiCommandBuffer::drawIndexed()}{drawIndexed()} supports the \c
+ vertexOffset argument. When reported as not supported, the vertexOffset
+ value in an indexed draw is ignored. In practice this feature will be
+ unsupported with OpenGL and OpenGL ES versions lower than 3.2, and with
+ Metal on older iOS devices, including the iOS Simulator.
\value BaseInstance Indicates that instanced draw commands support the \c
firstInstance argument. When reported as not supported, the firstInstance
- value is ignored and the instance ID starts from 0.
+ value is ignored and the instance ID starts from 0. In practice this feature
+ will be unsupported with OpenGL, and with Metal on older iOS devices,
+ including the iOS Simulator.
\value TriangleFanTopology Indicates that QRhiGraphicsPipeline::setTopology()
supports QRhiGraphicsPipeline::TriangleFan.
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 700b2e75bc..7bdedf7859 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -421,11 +421,13 @@ bool QRhiMetal::create(QRhi::Flags flags)
#if defined(Q_OS_MACOS)
caps.maxTextureSize = 16384;
+ caps.baseVertexAndInstance = true;
#elif defined(Q_OS_TVOS)
if ([d->dev supportsFeatureSet: MTLFeatureSet(30003)]) // MTLFeatureSet_tvOS_GPUFamily2_v1
caps.maxTextureSize = 16384;
else
caps.maxTextureSize = 8192;
+ caps.baseVertexAndInstance = false;
#elif defined(Q_OS_IOS)
// welcome to feature set hell
if ([d->dev supportsFeatureSet: MTLFeatureSet(16)] // MTLFeatureSet_iOS_GPUFamily5_v1
@@ -433,12 +435,15 @@ bool QRhiMetal::create(QRhi::Flags flags)
|| [d->dev supportsFeatureSet: MTLFeatureSet(4)]) // MTLFeatureSet_iOS_GPUFamily3_v1
{
caps.maxTextureSize = 16384;
+ caps.baseVertexAndInstance = true;
} else if ([d->dev supportsFeatureSet: MTLFeatureSet(3)] // MTLFeatureSet_iOS_GPUFamily2_v2
|| [d->dev supportsFeatureSet: MTLFeatureSet(2)]) // MTLFeatureSet_iOS_GPUFamily1_v2
{
caps.maxTextureSize = 8192;
+ caps.baseVertexAndInstance = false;
} else {
caps.maxTextureSize = 4096;
+ caps.baseVertexAndInstance = false;
}
#endif
@@ -582,9 +587,9 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const
case QRhi::VertexShaderPointSize:
return true;
case QRhi::BaseVertex:
- return true;
+ return caps.baseVertexAndInstance;
case QRhi::BaseInstance:
- return true;
+ return caps.baseVertexAndInstance;
case QRhi::TriangleFanTopology:
return false;
case QRhi::ReadBackNonUniformBuffer:
@@ -1333,14 +1338,23 @@ void QRhiMetal::drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount,
QMetalBuffer *ibufD = QRHI_RES(QMetalBuffer, cbD->currentIndexBuffer);
id<MTLBuffer> mtlbuf = ibufD->d->buf[ibufD->d->slotted ? currentFrameSlot : 0];
- [cbD->d->currentRenderPassEncoder drawIndexedPrimitives: QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->d->primitiveType
- indexCount: indexCount
- indexType: cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
- indexBuffer: mtlbuf
- indexBufferOffset: indexOffset
- instanceCount: instanceCount
- baseVertex: vertexOffset
- baseInstance: firstInstance];
+ if (caps.baseVertexAndInstance) {
+ [cbD->d->currentRenderPassEncoder drawIndexedPrimitives: QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->d->primitiveType
+ indexCount: indexCount
+ indexType: cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
+ indexBuffer: mtlbuf
+ indexBufferOffset: indexOffset
+ instanceCount: instanceCount
+ baseVertex: vertexOffset
+ baseInstance: firstInstance];
+ } else {
+ [cbD->d->currentRenderPassEncoder drawIndexedPrimitives: QRHI_RES(QMetalGraphicsPipeline, cbD->currentGraphicsPipeline)->d->primitiveType
+ indexCount: indexCount
+ indexType: cbD->currentIndexFormat == QRhiCommandBuffer::IndexUInt16 ? MTLIndexTypeUInt16 : MTLIndexTypeUInt32
+ indexBuffer: mtlbuf
+ indexBufferOffset: indexOffset
+ instanceCount: instanceCount];
+ }
}
void QRhiMetal::debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name)
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index c8ba5940a8..6fb1885b05 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -475,6 +475,7 @@ public:
struct {
int maxTextureSize = 4096;
+ bool baseVertexAndInstance = true;
} caps;
QRhiMetalData *d = nullptr;