diff options
Diffstat (limited to 'src/gui/rhi/qrhivulkan.cpp')
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 54 |
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); |