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>
This commit is contained in:
parent
afe0bf0914
commit
09597d05f7
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user