diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2023-05-24 14:26:49 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2023-05-30 10:29:55 +0200 |
commit | 09597d05f7cb966c9bdc659caa2a8a0a2f6f29b5 (patch) | |
tree | 329b6b2304d7cad138723c540f43b446f1978745 /src | |
parent | afe0bf0914362ff6f8e83ebd17f6cc346805a072 (diff) |
rhi: avoid backends modifying the frontend depth and arraySize
Buffer and texture sizes (size, pixelSize) may get increased, if needed,
but those actual sizes calculated by the QRhi backends are not written
back to the QRhiBuffer m_size or QRhiTexture m_pixelSize.
In contrast, both m_depth and m_arraySize are clamped in QRhiTexture
by most backends (to ensure a lower bound of 1 and 0, respectively).
This is not great since it means the getters for depth() and arraySize()
may return values different from what the user has provided. To avoid
confusion, do not modify the m_* variables.
Change-Id: I2cc5b9abf41ea108549ffd7f2403306e6e8ebba2
Reviewed-by: Jonas Karlsson <jonas.karlsson@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/rhi/qrhid3d11.cpp | 16 | ||||
-rw-r--r-- | src/gui/rhi/qrhid3d12.cpp | 15 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 26 | ||||
-rw-r--r-- | src/gui/rhi/qrhimetal.mm | 9 | ||||
-rw-r--r-- | src/gui/rhi/qrhinull.cpp | 7 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 14 |
6 files changed, 42 insertions, 45 deletions
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index 1b1afeda4d..76e0d9d420 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -3235,12 +3235,10 @@ bool QD3D11Texture::prepareCreate(QSize *adjustedSize) qWarning("Texture cannot be both 1D 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; @@ -3280,7 +3278,7 @@ bool QD3D11Texture::finishCreate() srvDesc.Texture1DArray.ArraySize = UINT(m_arrayRangeLength); } else { srvDesc.Texture1DArray.FirstArraySlice = 0; - srvDesc.Texture1DArray.ArraySize = UINT(m_arraySize); + srvDesc.Texture1DArray.ArraySize = UINT(qMax(0, m_arraySize)); } } else { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D; @@ -3294,7 +3292,7 @@ bool QD3D11Texture::finishCreate() srvDesc.Texture2DMSArray.ArraySize = UINT(m_arrayRangeLength); } else { srvDesc.Texture2DMSArray.FirstArraySlice = 0; - srvDesc.Texture2DMSArray.ArraySize = UINT(m_arraySize); + srvDesc.Texture2DMSArray.ArraySize = UINT(qMax(0, m_arraySize)); } } else { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; @@ -3304,7 +3302,7 @@ bool QD3D11Texture::finishCreate() srvDesc.Texture2DArray.ArraySize = UINT(m_arrayRangeLength); } else { srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.ArraySize = UINT(m_arraySize); + srvDesc.Texture2DArray.ArraySize = UINT(qMax(0, m_arraySize)); } } } else { @@ -3367,7 +3365,7 @@ bool QD3D11Texture::create() D3D11_TEXTURE1D_DESC desc = {}; desc.Width = UINT(size.width()); desc.MipLevels = mipLevelCount; - desc.ArraySize = isArray ? UINT(m_arraySize) : 1; + desc.ArraySize = isArray ? UINT(qMax(0, m_arraySize)) : 1; desc.Format = dxgiFormat; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = bindFlags; @@ -3387,7 +3385,7 @@ bool QD3D11Texture::create() desc.Width = UINT(size.width()); desc.Height = UINT(size.height()); desc.MipLevels = mipLevelCount; - desc.ArraySize = isCube ? 6 : (isArray ? UINT(m_arraySize) : 1); + desc.ArraySize = isCube ? 6 : (isArray ? UINT(qMax(0, m_arraySize)) : 1); desc.Format = dxgiFormat; desc.SampleDesc = sampleDesc; desc.Usage = D3D11_USAGE_DEFAULT; @@ -3406,7 +3404,7 @@ bool QD3D11Texture::create() D3D11_TEXTURE3D_DESC desc = {}; desc.Width = UINT(size.width()); desc.Height = UINT(size.height()); - desc.Depth = UINT(m_depth); + desc.Depth = UINT(qMax(1, m_depth)); desc.MipLevels = mipLevelCount; desc.Format = dxgiFormat; desc.Usage = D3D11_USAGE_DEFAULT; @@ -3479,7 +3477,7 @@ ID3D11UnorderedAccessView *QD3D11Texture::unorderedAccessViewForLevel(int level) desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY; desc.Texture2DArray.MipSlice = UINT(level); desc.Texture2DArray.FirstArraySlice = 0; - desc.Texture2DArray.ArraySize = UINT(m_arraySize); + desc.Texture2DArray.ArraySize = UINT(qMax(0, m_arraySize)); } else if (is3D) { desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; desc.Texture3D.MipSlice = UINT(level); diff --git a/src/gui/rhi/qrhid3d12.cpp b/src/gui/rhi/qrhid3d12.cpp index c6d3f59058..6c58a4d008 100644 --- a/src/gui/rhi/qrhid3d12.cpp +++ b/src/gui/rhi/qrhid3d12.cpp @@ -870,7 +870,7 @@ void QRhiD3D12::visitStorageImage(QD3D12Stage s, uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; uavDesc.Texture2DArray.MipSlice = UINT(d.level); uavDesc.Texture2DArray.FirstArraySlice = 0; - uavDesc.Texture2DArray.ArraySize = UINT(texD->m_arraySize); + uavDesc.Texture2DArray.ArraySize = UINT(qMax(0, texD->m_arraySize)); } else if (is3D) { uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D; uavDesc.Texture3D.MipSlice = UINT(d.level); @@ -3974,12 +3974,10 @@ bool QD3D12Texture::prepareCreate(QSize *adjustedSize) qWarning("Texture cannot be both 1D 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; @@ -4021,7 +4019,7 @@ bool QD3D12Texture::finishCreate() srvDesc.Texture1DArray.ArraySize = UINT(m_arrayRangeLength); } else { srvDesc.Texture1DArray.FirstArraySlice = 0; - srvDesc.Texture1DArray.ArraySize = UINT(m_arraySize); + srvDesc.Texture1DArray.ArraySize = UINT(qMax(0, m_arraySize)); } } else { srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D; @@ -4035,7 +4033,7 @@ bool QD3D12Texture::finishCreate() srvDesc.Texture2DMSArray.ArraySize = UINT(m_arrayRangeLength); } else { srvDesc.Texture2DMSArray.FirstArraySlice = 0; - srvDesc.Texture2DMSArray.ArraySize = UINT(m_arraySize); + srvDesc.Texture2DMSArray.ArraySize = UINT(qMax(0, m_arraySize)); } } else { srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; @@ -4045,7 +4043,7 @@ bool QD3D12Texture::finishCreate() srvDesc.Texture2DArray.ArraySize = UINT(m_arrayRangeLength); } else { srvDesc.Texture2DArray.FirstArraySlice = 0; - srvDesc.Texture2DArray.ArraySize = UINT(m_arraySize); + srvDesc.Texture2DArray.ArraySize = UINT(qMax(0, m_arraySize)); } } } else { @@ -4118,7 +4116,10 @@ bool QD3D12Texture::create() : D3D12_RESOURCE_DIMENSION_TEXTURE2D); resourceDesc.Width = UINT64(size.width()); resourceDesc.Height = UINT(size.height()); - resourceDesc.DepthOrArraySize = isCube ? 6 : (isArray ? UINT(m_arraySize) : (is3D ? m_depth : 1)); + resourceDesc.DepthOrArraySize = isCube ? 6 + : (isArray ? UINT(qMax(0, m_arraySize)) + : (is3D ? qMax(1, m_depth) + : 1)); resourceDesc.MipLevels = mipLevelCount; resourceDesc.Format = dxgiFormat; resourceDesc.SampleDesc = sampleDesc; diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 806e17c1a6..37e3373c21 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -2239,6 +2239,8 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb cmd.args.subImage.rowLength = 0; cmd.args.subImage.data = cbD->retainImage(img); } else if (!rawData.isEmpty() && isCompressed) { + const int depth = qMax(1, texD->m_depth); + const int arraySize = qMax(0, texD->m_arraySize); if ((texD->flags().testFlag(QRhiTexture::UsedAsCompressedAtlas) || is3D || isArray) && !texD->zeroInitialized) { @@ -2250,9 +2252,9 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb quint32 byteSize = 0; compressedFormatInfo(texD->m_format, texD->m_pixelSize, nullptr, &byteSize, nullptr); if (is3D) - byteSize *= texD->m_depth; + byteSize *= depth; if (isArray) - byteSize *= texD->m_arraySize; + byteSize *= arraySize; QByteArray zeroBuf(byteSize, 0); QGles2CommandBuffer::Command &cmd(cbD->commands.get()); cmd.cmd = QGles2CommandBuffer::Command::CompressedImage; @@ -2262,9 +2264,8 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb cmd.args.compressedImage.level = level; cmd.args.compressedImage.glintformat = texD->glintformat; cmd.args.compressedImage.w = texD->m_pixelSize.width(); - cmd.args.compressedImage.h = - is1D && isArray ? texD->m_arraySize : texD->m_pixelSize.height(); - cmd.args.compressedImage.depth = is3D ? texD->m_depth : (isArray ? texD->m_arraySize : 0); + cmd.args.compressedImage.h = is1D && isArray ? arraySize : texD->m_pixelSize.height(); + cmd.args.compressedImage.depth = is3D ? depth : (isArray ? arraySize : 0); cmd.args.compressedImage.size = byteSize; cmd.args.compressedImage.data = cbD->retainData(zeroBuf); texD->zeroInitialized = true; @@ -2296,8 +2297,8 @@ void QRhiGles2::enqueueSubresUpload(QGles2Texture *texD, QGles2CommandBuffer *cb cmd.args.compressedImage.level = level; cmd.args.compressedImage.glintformat = texD->glintformat; cmd.args.compressedImage.w = size.width(); - cmd.args.compressedImage.h = is1D && isArray ? texD->m_arraySize : size.height(); - cmd.args.compressedImage.depth = is3D ? texD->m_depth : (isArray ? texD->m_arraySize : 0); + cmd.args.compressedImage.h = is1D && isArray ? arraySize : size.height(); + cmd.args.compressedImage.depth = is3D ? depth : (isArray ? arraySize : 0); cmd.args.compressedImage.size = rawData.size(); cmd.args.compressedImage.data = cbD->retainData(rawData); } @@ -5209,12 +5210,10 @@ bool QGles2Texture::prepareCreate(QSize *adjustedSize) 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; @@ -5289,13 +5288,13 @@ bool QGles2Texture::create() const QSize mipSize = rhiD->q->sizeForMipLevel(level, size); if (isArray) rhiD->f->glTexImage2D(target, level, GLint(glintformat), mipSize.width(), - m_arraySize, 0, glformat, gltype, nullptr); + qMax(0, m_arraySize), 0, glformat, gltype, nullptr); else rhiD->glTexImage1D(target, level, GLint(glintformat), mipSize.width(), 0, glformat, gltype, nullptr); } } else if (is3D || isArray) { - const int layerCount = is3D ? m_depth : m_arraySize; + const int layerCount = is3D ? qMax(1, m_depth) : qMax(0, m_arraySize); if (hasMipMaps) { for (int level = 0; level != mipLevelCount; ++level) { const QSize mipSize = rhiD->q->sizeForMipLevel(level, size); @@ -5327,10 +5326,11 @@ bool QGles2Texture::create() if (is1D && !isArray) rhiD->glTexStorage1D(target, mipLevelCount, glsizedintformat, size.width()); else if (!is1D && (is3D || isArray)) - rhiD->f->glTexStorage3D(target, mipLevelCount, glsizedintformat, size.width(), size.height(), is3D ? m_depth : m_arraySize); + rhiD->f->glTexStorage3D(target, mipLevelCount, glsizedintformat, size.width(), size.height(), + is3D ? qMax(1, m_depth) : qMax(0, m_arraySize)); else rhiD->f->glTexStorage2D(target, mipLevelCount, glsizedintformat, size.width(), - is1D ? m_arraySize : size.height()); + is1D ? qMax(0, m_arraySize) : size.height()); } specified = true; } else { diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm index 57f5aefdd4..d0eb805c42 100644 --- a/src/gui/rhi/qrhimetal.mm +++ b/src/gui/rhi/qrhimetal.mm @@ -3709,12 +3709,10 @@ bool QMetalTexture::prepareCreate(QSize *adjustedSize) qWarning("Texture cannot be both 1D and cube"); 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; @@ -3764,12 +3762,12 @@ bool QMetalTexture::create() desc.pixelFormat = d->format; desc.width = NSUInteger(size.width()); desc.height = NSUInteger(size.height()); - desc.depth = is3D ? m_depth : 1; + desc.depth = is3D ? qMax(1, m_depth) : 1; desc.mipmapLevelCount = NSUInteger(mipLevelCount); if (samples > 1) desc.sampleCount = NSUInteger(samples); if (isArray) - desc.arrayLength = NSUInteger(m_arraySize); + desc.arrayLength = NSUInteger(qMax(0, m_arraySize)); desc.resourceOptions = MTLResourceStorageModePrivate; desc.storageMode = MTLStorageModePrivate; desc.usage = MTLTextureUsageShaderRead; @@ -3828,7 +3826,8 @@ id<MTLTexture> QMetalTextureData::viewForLevel(int level) 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 : (isArray ? q->m_arraySize : 1))]; + levels: NSMakeRange(NSUInteger(level), 1) + slices: NSMakeRange(0, isCube ? 6 : (isArray ? qMax(0, q->m_arraySize) : 1))]; perLevelViews[level] = view; return view; diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp index 6d87baaec0..95106bfeb8 100644 --- a/src/gui/rhi/qrhinull.cpp +++ b/src/gui/rhi/qrhinull.cpp @@ -676,10 +676,11 @@ bool QNullTexture::create() const bool is1D = m_flags.testFlags(OneDimensional); QSize size = is1D ? QSize(qMax(1, m_pixelSize.width()), 1) : (m_pixelSize.isEmpty() ? QSize(1, 1) : m_pixelSize); - m_depth = qMax(1, m_depth); const int mipLevelCount = hasMipMaps ? rhiD->q->mipLevelsForSize(size) : 1; - m_arraySize = qMax(0, m_arraySize); - const int layerCount = is3D ? m_depth : (isCube ? 6 : (isArray ? m_arraySize : 1)); + const int layerCount = is3D ? qMax(1, m_depth) + : (isCube ? 6 + : (isArray ? qMax(0, m_arraySize) + : 1)); if (m_format == RGBA8) { image.resize(layerCount); diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index a0e6a467bb..822e71647b 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -3598,10 +3598,10 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat if (!origStage) origStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - for (int layer = 0; layer < (isCube ? 6 : (isArray ? utexD->m_arraySize : 1)); ++layer) { + for (int layer = 0; layer < (isCube ? 6 : (isArray ? qMax(0, utexD->m_arraySize) : 1)); ++layer) { int w = utexD->m_pixelSize.width(); int h = utexD->m_pixelSize.height(); - int depth = is3D ? utexD->m_depth : 1; + int depth = is3D ? qMax(1, utexD->m_depth) : 1; for (int level = 1; level < int(utexD->mipLevelCount); ++level) { if (level == 1) { subresourceBarrier(cbD, utexD->image, @@ -6112,12 +6112,10 @@ bool QVkTexture::prepareCreate(QSize *adjustedSize) qWarning("Texture cannot be both 1D 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; @@ -6166,7 +6164,7 @@ bool QVkTexture::finishCreate() viewInfo.subresourceRange.baseArrayLayer = uint32_t(m_arrayRangeStart); viewInfo.subresourceRange.layerCount = uint32_t(m_arrayRangeLength); } else { - viewInfo.subresourceRange.layerCount = isCube ? 6 : (isArray ? m_arraySize : 1); + viewInfo.subresourceRange.layerCount = isCube ? 6 : (isArray ? qMax(0, m_arraySize) : 1); } VkResult err = rhiD->df->vkCreateImageView(rhiD->dev, &viewInfo, nullptr, &imageView); @@ -6220,9 +6218,9 @@ bool QVkTexture::create() imageInfo.format = vkformat; imageInfo.extent.width = uint32_t(size.width()); imageInfo.extent.height = uint32_t(size.height()); - imageInfo.extent.depth = is3D ? m_depth : 1; + imageInfo.extent.depth = is3D ? qMax(1, m_depth) : 1; imageInfo.mipLevels = mipLevelCount; - imageInfo.arrayLayers = isCube ? 6 : (isArray ? m_arraySize : 1); + imageInfo.arrayLayers = isCube ? 6 : (isArray ? qMax(0, m_arraySize) : 1); imageInfo.samples = samples; imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; @@ -6323,7 +6321,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 : (isArray ? m_arraySize : 1); + viewInfo.subresourceRange.layerCount = isCube ? 6 : (isArray ? qMax(0, m_arraySize) : 1); VkImageView v = VK_NULL_HANDLE; QRHI_RES_RHI(QRhiVulkan); |