diff options
Diffstat (limited to 'src/gui/rhi/qrhimetal.mm')
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index d37a130d15..3e4c0e08e2 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -613,6 +613,8 @@ bool QRhiMetal::isFeatureSupported(QRhi::Feature feature) const return true; case QRhi::RenderTo3DTextureSlice: return true; + case QRhi::TextureArrays: + return true; default: Q_UNREACHABLE(); return false; @@ -646,6 +648,8 @@ int QRhiMetal::resourceLimit(QRhi::ResourceLimit limit) const #else return 512; #endif + case QRhi::TextureArraySizeMax: + return 2048; default: Q_UNREACHABLE(); return 0; @@ -704,10 +708,10 @@ QRhiRenderBuffer *QRhiMetal::createRenderBuffer(QRhiRenderBuffer::Type type, con } QRhiTexture *QRhiMetal::createTexture(QRhiTexture::Format format, - const QSize &pixelSize, int depth, + const QSize &pixelSize, int depth, int arraySize, int sampleCount, QRhiTexture::Flags flags) { - return new QMetalTexture(this, format, pixelSize, depth, sampleCount, flags); + return new QMetalTexture(this, format, pixelSize, depth, arraySize, sampleCount, flags); } QRhiSampler *QRhiMetal::createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, @@ -2617,8 +2621,8 @@ QRhiTexture::Format QMetalRenderBuffer::backingFormat() const } QMetalTexture::QMetalTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, int depth, - int sampleCount, Flags flags) - : QRhiTexture(rhi, format, pixelSize, depth, sampleCount, flags), + int arraySize, int sampleCount, Flags flags) + : QRhiTexture(rhi, format, pixelSize, depth, arraySize, sampleCount, flags), d(new QMetalTextureData(this)) { for (int i = 0; i < QMTL_FRAMES_IN_FLIGHT; ++i) @@ -2673,6 +2677,7 @@ bool QMetalTexture::prepareCreate(QSize *adjustedSize) const QSize size = m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize; const bool isCube = m_flags.testFlag(CubeMap); const bool is3D = m_flags.testFlag(ThreeDimensional); + const bool isArray = m_flags.testFlag(TextureArray); const bool hasMipMaps = m_flags.testFlag(MipMapped); QRHI_RES_RHI(QRhiMetal); @@ -2697,11 +2702,24 @@ bool QMetalTexture::prepareCreate(QSize *adjustedSize) qWarning("Texture cannot be both cube and 3D"); return false; } + if (isArray && is3D) { + qWarning("Texture cannot be both array and 3D"); + return false; + } m_depth = qMax(1, m_depth); if (m_depth > 1 && !is3D) { qWarning("Texture cannot have a depth of %d when it is not 3D", m_depth); return false; } + m_arraySize = qMax(0, m_arraySize); + if (m_arraySize > 0 && !isArray) { + qWarning("Texture cannot have an array size of %d when it is not an array", m_arraySize); + return false; + } + if (m_arraySize < 1 && isArray) { + qWarning("Texture is an array but array size is %d", m_arraySize); + return false; + } if (adjustedSize) *adjustedSize = size; @@ -2719,12 +2737,24 @@ bool QMetalTexture::create() const bool isCube = m_flags.testFlag(CubeMap); const bool is3D = m_flags.testFlag(ThreeDimensional); - if (isCube) + const bool isArray = m_flags.testFlag(TextureArray); + if (isCube) { desc.textureType = MTLTextureTypeCube; - else if (is3D) + } else if (is3D) { desc.textureType = MTLTextureType3D; - else + } else if (isArray) { +#ifdef Q_OS_IOS + if (samples > 1) { + // would be available on iOS 14.0+ but cannot test for that with a 13 SDK + qWarning("Multisample 2D texture array is not supported on iOS"); + } + desc.textureType = MTLTextureType2DArray; +#else + desc.textureType = samples > 1 ? MTLTextureType2DMultisampleArray : MTLTextureType2DArray; +#endif + } else { desc.textureType = samples > 1 ? MTLTextureType2DMultisample : MTLTextureType2D; + } desc.pixelFormat = d->format; desc.width = NSUInteger(size.width()); desc.height = NSUInteger(size.height()); @@ -2732,6 +2762,8 @@ bool QMetalTexture::create() desc.mipmapLevelCount = NSUInteger(mipLevelCount); if (samples > 1) desc.sampleCount = NSUInteger(samples); + if (isArray) + desc.arrayLength = NSUInteger(m_arraySize); desc.resourceOptions = MTLResourceStorageModePrivate; desc.storageMode = MTLStorageModePrivate; desc.usage = MTLTextureUsageShaderRead; @@ -2750,7 +2782,7 @@ bool QMetalTexture::create() d->owns = true; QRHI_PROF; - QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : 1, samples)); + QRHI_PROF_F(newTexture(this, true, mipLevelCount, isCube ? 6 : (isArray ? m_arraySize : 1), samples)); lastActiveFrameSlot = -1; generation += 1; @@ -2794,8 +2826,9 @@ id<MTLTexture> QMetalTextureData::viewForLevel(int level) const MTLTextureType type = [tex textureType]; const bool isCube = q->m_flags.testFlag(QRhiTexture::CubeMap); + const bool isArray = q->m_flags.testFlag(QRhiTexture::TextureArray); id<MTLTexture> view = [tex newTextureViewWithPixelFormat: format textureType: type - levels: NSMakeRange(NSUInteger(level), 1) slices: NSMakeRange(0, isCube ? 6 : 1)]; + levels: NSMakeRange(NSUInteger(level), 1) slices: NSMakeRange(0, isCube ? 6 : (isArray ? q->m_arraySize : 1))]; perLevelViews[level] = view; return view; |