summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-09-23 15:40:06 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-09-25 09:24:25 +0200
commit60871b4fdf1ec977498ec4baa1d33c0972ac434f (patch)
tree0ade7fd3236119cf8e9698f1958a5665339e2704 /src
parent342a8f29ea542ff8b65453888a7cc9644dbe66cc (diff)
rhi: vulkan: Fix mipmap generation for cubemaps
Change-Id: Ia1aab06214be802aaabc97ffefa28947e11148e3 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/rhi/qrhi.cpp11
-rw-r--r--src/gui/rhi/qrhi_p.h2
-rw-r--r--src/gui/rhi/qrhi_p_p.h4
-rw-r--r--src/gui/rhi/qrhivulkan.cpp144
4 files changed, 81 insertions, 80 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 849519cb7a..17a1ca91e2 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -4963,19 +4963,20 @@ void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb,
}
/*!
- Enqueues a mipmap generation operation for the specified \a layer of texture
- \a tex.
+ Enqueues a mipmap generation operation for the specified texture \a tex.
+
+ Both 2D and cube textures are supported.
\note The texture must be created with QRhiTexture::MipMapped and
QRhiTexture::UsedWithGenerateMips.
*/
-void QRhiResourceUpdateBatch::generateMips(QRhiTexture *tex, int layer)
+void QRhiResourceUpdateBatch::generateMips(QRhiTexture *tex)
{
const int idx = d->activeTextureOpCount++;
if (idx < d->textureOps.size())
- d->textureOps[idx] = QRhiResourceUpdateBatchPrivate::TextureOp::genMips(tex, layer);
+ d->textureOps[idx] = QRhiResourceUpdateBatchPrivate::TextureOp::genMips(tex);
else
- d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::genMips(tex, layer));
+ d->textureOps.append(QRhiResourceUpdateBatchPrivate::TextureOp::genMips(tex));
}
/*!
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 1e86cbc04a..bdfaec9fdf 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1413,7 +1413,7 @@ public:
void uploadTexture(QRhiTexture *tex, const QImage &image);
void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription());
void readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result);
- void generateMips(QRhiTexture *tex, int layer = 0);
+ void generateMips(QRhiTexture *tex);
private:
QRhiResourceUpdateBatch(QRhiImplementation *rhi);
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 13f1c88f2d..0128fd2d4e 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -393,7 +393,6 @@ public:
QRhiTextureCopyDescription desc;
QRhiReadbackDescription rb;
QRhiReadbackResult *result;
- int layer;
static TextureOp upload(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
{
@@ -424,12 +423,11 @@ public:
return op;
}
- static TextureOp genMips(QRhiTexture *tex, int layer)
+ static TextureOp genMips(QRhiTexture *tex)
{
TextureOp op = {};
op.type = GenMips;
op.dst = tex;
- op.layer = layer;
return op;
}
};
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 835db74804..1a0431e19d 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -3318,8 +3318,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
} else if (u.type == QRhiResourceUpdateBatchPrivate::TextureOp::GenMips) {
QVkTexture *utexD = QRHI_RES(QVkTexture, u.dst);
Q_ASSERT(utexD->m_flags.testFlag(QRhiTexture::UsedWithGenerateMips));
- int w = utexD->m_pixelSize.width();
- int h = utexD->m_pixelSize.height();
+ const bool isCube = utexD->m_flags.testFlag(QRhiTexture::CubeMap);
VkImageLayout origLayout = utexD->usageState.layout;
VkAccessFlags origAccess = utexD->usageState.access;
@@ -3327,80 +3326,83 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
if (!origStage)
origStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
- for (int level = 1; level < int(utexD->mipLevelCount); ++level) {
- if (level == 1) {
+ for (int layer = 0; layer < (isCube ? 6 : 1); ++layer) {
+ int w = utexD->m_pixelSize.width();
+ int h = utexD->m_pixelSize.height();
+ for (int level = 1; level < int(utexD->mipLevelCount); ++level) {
+ if (level == 1) {
+ subresourceBarrier(cbD, utexD->image,
+ origLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ origAccess, VK_ACCESS_TRANSFER_READ_BIT,
+ origStage, VK_PIPELINE_STAGE_TRANSFER_BIT,
+ layer, 1,
+ level - 1, 1);
+ } else {
+ subresourceBarrier(cbD, utexD->image,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+ VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+ layer, 1,
+ level - 1, 1);
+ }
+
subresourceBarrier(cbD, utexD->image,
- origLayout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- origAccess, VK_ACCESS_TRANSFER_READ_BIT,
+ origLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+ origAccess, VK_ACCESS_TRANSFER_WRITE_BIT,
origStage, VK_PIPELINE_STAGE_TRANSFER_BIT,
- u.layer, 1,
- level - 1, 1);
- } else {
- subresourceBarrier(cbD, utexD->image,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
- u.layer, 1,
- level - 1, 1);
+ layer, 1,
+ level, 1);
+
+ VkImageBlit region;
+ memset(&region, 0, sizeof(region));
+
+ region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ region.srcSubresource.mipLevel = uint32_t(level) - 1;
+ region.srcSubresource.baseArrayLayer = uint32_t(layer);
+ region.srcSubresource.layerCount = 1;
+
+ region.srcOffsets[1].x = qMax(1, w);
+ region.srcOffsets[1].y = qMax(1, h);
+ region.srcOffsets[1].z = 1;
+
+ region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ region.dstSubresource.mipLevel = uint32_t(level);
+ region.dstSubresource.baseArrayLayer = uint32_t(layer);
+ region.dstSubresource.layerCount = 1;
+
+ region.dstOffsets[1].x = qMax(1, w >> 1);
+ region.dstOffsets[1].y = qMax(1, h >> 1);
+ region.dstOffsets[1].z = 1;
+
+ QVkCommandBuffer::Command cmd;
+ cmd.cmd = QVkCommandBuffer::Command::BlitImage;
+ cmd.args.blitImage.src = utexD->image;
+ cmd.args.blitImage.srcLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ cmd.args.blitImage.dst = utexD->image;
+ cmd.args.blitImage.dstLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ cmd.args.blitImage.filter = VK_FILTER_LINEAR;
+ cmd.args.blitImage.desc = region;
+ cbD->commands.append(cmd);
+
+ w >>= 1;
+ h >>= 1;
}
- subresourceBarrier(cbD, utexD->image,
- origLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- origAccess, VK_ACCESS_TRANSFER_WRITE_BIT,
- origStage, VK_PIPELINE_STAGE_TRANSFER_BIT,
- u.layer, 1,
- level, 1);
-
- VkImageBlit region;
- memset(&region, 0, sizeof(region));
-
- region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.srcSubresource.mipLevel = uint32_t(level) - 1;
- region.srcSubresource.baseArrayLayer = uint32_t(u.layer);
- region.srcSubresource.layerCount = 1;
-
- region.srcOffsets[1].x = qMax(1, w);
- region.srcOffsets[1].y = qMax(1, h);
- region.srcOffsets[1].z = 1;
-
- region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- region.dstSubresource.mipLevel = uint32_t(level);
- region.dstSubresource.baseArrayLayer = uint32_t(u.layer);
- region.dstSubresource.layerCount = 1;
-
- region.dstOffsets[1].x = qMax(1, w >> 1);
- region.dstOffsets[1].y = qMax(1, h >> 1);
- region.dstOffsets[1].z = 1;
-
- QVkCommandBuffer::Command cmd;
- cmd.cmd = QVkCommandBuffer::Command::BlitImage;
- cmd.args.blitImage.src = utexD->image;
- cmd.args.blitImage.srcLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
- cmd.args.blitImage.dst = utexD->image;
- cmd.args.blitImage.dstLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- cmd.args.blitImage.filter = VK_FILTER_LINEAR;
- cmd.args.blitImage.desc = region;
- cbD->commands.append(cmd);
-
- w >>= 1;
- h >>= 1;
- }
-
- if (utexD->mipLevelCount > 1) {
- subresourceBarrier(cbD, utexD->image,
- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, origLayout,
- VK_ACCESS_TRANSFER_READ_BIT, origAccess,
- VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
- u.layer, 1,
- 0, int(utexD->mipLevelCount) - 1);
- subresourceBarrier(cbD, utexD->image,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, origLayout,
- VK_ACCESS_TRANSFER_WRITE_BIT, origAccess,
- VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
- u.layer, 1,
- int(utexD->mipLevelCount) - 1, 1);
+ if (utexD->mipLevelCount > 1) {
+ subresourceBarrier(cbD, utexD->image,
+ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, origLayout,
+ VK_ACCESS_TRANSFER_READ_BIT, origAccess,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
+ layer, 1,
+ 0, int(utexD->mipLevelCount) - 1);
+ subresourceBarrier(cbD, utexD->image,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, origLayout,
+ VK_ACCESS_TRANSFER_WRITE_BIT, origAccess,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
+ layer, 1,
+ int(utexD->mipLevelCount) - 1, 1);
+ }
}
-
utexD->lastActiveFrameSlot = currentFrameSlot;
}
}