summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi/qrhivulkan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/rhi/qrhivulkan.cpp')
-rw-r--r--src/gui/rhi/qrhivulkan.cpp54
1 files changed, 42 insertions, 12 deletions
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 42d6f7e6ec..0bd3e6e95d 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -3454,6 +3454,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
QVkTexture *utexD = QRHI_RES(QVkTexture, u.dst);
Q_ASSERT(utexD->m_flags.testFlag(QRhiTexture::UsedWithGenerateMips));
const bool isCube = utexD->m_flags.testFlag(QRhiTexture::CubeMap);
+ const bool isArray = utexD->m_flags.testFlag(QRhiTexture::TextureArray);
const bool is3D = utexD->m_flags.testFlag(QRhiTexture::ThreeDimensional);
VkImageLayout origLayout = utexD->usageState.layout;
@@ -3462,7 +3463,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
if (!origStage)
origStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- for (int layer = 0; layer < (isCube ? 6 : 1); ++layer) {
+ for (int layer = 0; layer < (isCube ? 6 : (isArray ? utexD->m_arraySize : 1)); ++layer) {
int w = utexD->m_pixelSize.width();
int h = utexD->m_pixelSize.height();
int depth = is3D ? utexD->m_depth : 1;
@@ -4269,6 +4270,8 @@ bool QRhiVulkan::isFeatureSupported(QRhi::Feature feature) const
return true;
case QRhi::RenderTo3DTextureSlice:
return caps.texture3DSliceAs2D;
+ case QRhi::TextureArrays:
+ return true;
default:
Q_UNREACHABLE();
return false;
@@ -4300,6 +4303,8 @@ int QRhiVulkan::resourceLimit(QRhi::ResourceLimit limit) const
return int(physDevProperties.limits.maxComputeWorkGroupSize[1]);
case QRhi::MaxThreadGroupZ:
return int(physDevProperties.limits.maxComputeWorkGroupSize[2]);
+ case QRhi::TextureArraySizeMax:
+ return int(physDevProperties.limits.maxImageArrayLayers);
default:
Q_UNREACHABLE();
return 0;
@@ -4475,10 +4480,10 @@ QRhiRenderBuffer *QRhiVulkan::createRenderBuffer(QRhiRenderBuffer::Type type, co
}
QRhiTexture *QRhiVulkan::createTexture(QRhiTexture::Format format,
- const QSize &pixelSize, int depth,
+ const QSize &pixelSize, int depth, int arraySize,
int sampleCount, QRhiTexture::Flags flags)
{
- return new QVkTexture(this, format, pixelSize, depth, sampleCount, flags);
+ return new QVkTexture(this, format, pixelSize, depth, arraySize, sampleCount, flags);
}
QRhiSampler *QRhiVulkan::createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter,
@@ -5713,6 +5718,7 @@ bool QVkRenderBuffer::create()
backingTexture = QRHI_RES(QVkTexture, rhiD->createTexture(backingFormat(),
m_pixelSize,
1,
+ 0,
m_sampleCount,
QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource));
} else {
@@ -5762,8 +5768,8 @@ QRhiTexture::Format QVkRenderBuffer::backingFormat() const
}
QVkTexture::QVkTexture(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)
{
for (int i = 0; i < QVK_FRAMES_IN_FLIGHT; ++i) {
stagingBuffers[i] = VK_NULL_HANDLE;
@@ -5834,6 +5840,7 @@ bool QVkTexture::prepareCreate(QSize *adjustedSize)
const QSize size = m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize;
const bool isCube = m_flags.testFlag(CubeMap);
+ const bool isArray = m_flags.testFlag(TextureArray);
const bool is3D = m_flags.testFlag(ThreeDimensional);
const bool hasMipMaps = m_flags.testFlag(MipMapped);
@@ -5862,11 +5869,24 @@ bool QVkTexture::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;
+ }
usageState.layout = VK_IMAGE_LAYOUT_PREINITIALIZED;
usageState.access = 0;
@@ -5884,13 +5904,16 @@ bool QVkTexture::finishCreate()
const auto aspectMask = aspectMaskForTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
+ const bool isArray = m_flags.testFlag(TextureArray);
const bool is3D = m_flags.testFlag(ThreeDimensional);
VkImageViewCreateInfo viewInfo;
memset(&viewInfo, 0, sizeof(viewInfo));
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;
- viewInfo.viewType = isCube ? VK_IMAGE_VIEW_TYPE_CUBE : (is3D ? VK_IMAGE_VIEW_TYPE_3D : VK_IMAGE_VIEW_TYPE_2D);
+ viewInfo.viewType = isCube ? VK_IMAGE_VIEW_TYPE_CUBE
+ : (is3D ? VK_IMAGE_VIEW_TYPE_3D
+ : (isArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D));
viewInfo.format = vkformat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
@@ -5898,7 +5921,7 @@ bool QVkTexture::finishCreate()
viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
viewInfo.subresourceRange.aspectMask = aspectMask;
viewInfo.subresourceRange.levelCount = mipLevelCount;
- viewInfo.subresourceRange.layerCount = isCube ? 6 : 1;
+ viewInfo.subresourceRange.layerCount = isCube ? 6 : (isArray ? m_arraySize : 1);
VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &imageView);
if (err != VK_SUCCESS) {
@@ -5922,6 +5945,7 @@ bool QVkTexture::create()
const bool isRenderTarget = m_flags.testFlag(QRhiTexture::RenderTarget);
const bool isDepth = isDepthTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
+ const bool isArray = m_flags.testFlag(TextureArray);
const bool is3D = m_flags.testFlag(ThreeDimensional);
VkImageCreateInfo imageInfo;
@@ -5952,7 +5976,7 @@ bool QVkTexture::create()
imageInfo.extent.height = uint32_t(size.height());
imageInfo.extent.depth = is3D ? m_depth : 1;
imageInfo.mipLevels = mipLevelCount;
- imageInfo.arrayLayers = isCube ? 6 : 1;
+ imageInfo.arrayLayers = isCube ? 6 : (isArray ? m_arraySize : 1);
imageInfo.samples = samples;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
@@ -5989,7 +6013,7 @@ bool QVkTexture::create()
rhiD->setObjectName(uint64_t(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, m_objectName);
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : 1, samples));
+ QRHI_PROF_F(newTexture(this, true, int(mipLevelCount), isCube ? 6 : (isArray ? m_arraySize : 1), samples));
owns = true;
rhiD->registerResource(this);
@@ -6010,8 +6034,11 @@ bool QVkTexture::createFrom(QRhiTexture::NativeTexture src)
if (!finishCreate())
return false;
+ const bool isCube = m_flags.testFlag(CubeMap);
+ const bool isArray = m_flags.testFlag(TextureArray);
+
QRHI_PROF;
- QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), m_flags.testFlag(CubeMap) ? 6 : 1, samples));
+ QRHI_PROF_F(newTexture(this, false, int(mipLevelCount), isCube ? 6 : (isArray ? m_arraySize : 1), samples));
usageState.layout = VkImageLayout(src.layout);
@@ -6039,13 +6066,16 @@ VkImageView QVkTexture::imageViewForLevel(int level)
const VkImageAspectFlags aspectMask = aspectMaskForTextureFormat(m_format);
const bool isCube = m_flags.testFlag(CubeMap);
+ const bool isArray = m_flags.testFlag(TextureArray);
const bool is3D = m_flags.testFlag(ThreeDimensional);
VkImageViewCreateInfo viewInfo;
memset(&viewInfo, 0, sizeof(viewInfo));
viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
viewInfo.image = image;
- viewInfo.viewType = isCube ? VK_IMAGE_VIEW_TYPE_CUBE : (is3D ? VK_IMAGE_VIEW_TYPE_3D : VK_IMAGE_VIEW_TYPE_2D);
+ viewInfo.viewType = isCube ? VK_IMAGE_VIEW_TYPE_CUBE
+ : (is3D ? VK_IMAGE_VIEW_TYPE_3D
+ : (isArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D));
viewInfo.format = vkformat;
viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
@@ -6055,7 +6085,7 @@ VkImageView QVkTexture::imageViewForLevel(int level)
viewInfo.subresourceRange.baseMipLevel = uint32_t(level);
viewInfo.subresourceRange.levelCount = 1;
viewInfo.subresourceRange.baseArrayLayer = 0;
- viewInfo.subresourceRange.layerCount = isCube ? 6 : 1;
+ viewInfo.subresourceRange.layerCount = isCube ? 6 : (isArray ? m_arraySize : 1);
VkImageView v = VK_NULL_HANDLE;
QRHI_RES_RHI(QRhiVulkan);