summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhimetal.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/rhi/qrhimetal.mm')
-rw-r--r--src/gui/rhi/qrhimetal.mm51
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;