rhi: vulkan: Fix mipmap generation for cubemaps
Change-Id: Ia1aab06214be802aaabc97ffefa28947e11148e3 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
This commit is contained in:
parent
342a8f29ea
commit
60871b4fdf
@ -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));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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,20 +3326,23 @@ 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) {
|
||||
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,
|
||||
u.layer, 1,
|
||||
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,
|
||||
layer, 1,
|
||||
level - 1, 1);
|
||||
}
|
||||
|
||||
@ -3348,7 +3350,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
|
||||
origLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
origAccess, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
origStage, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
u.layer, 1,
|
||||
layer, 1,
|
||||
level, 1);
|
||||
|
||||
VkImageBlit region;
|
||||
@ -3356,7 +3358,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
|
||||
|
||||
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.srcSubresource.mipLevel = uint32_t(level) - 1;
|
||||
region.srcSubresource.baseArrayLayer = uint32_t(u.layer);
|
||||
region.srcSubresource.baseArrayLayer = uint32_t(layer);
|
||||
region.srcSubresource.layerCount = 1;
|
||||
|
||||
region.srcOffsets[1].x = qMax(1, w);
|
||||
@ -3365,7 +3367,7 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
|
||||
|
||||
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
region.dstSubresource.mipLevel = uint32_t(level);
|
||||
region.dstSubresource.baseArrayLayer = uint32_t(u.layer);
|
||||
region.dstSubresource.baseArrayLayer = uint32_t(layer);
|
||||
region.dstSubresource.layerCount = 1;
|
||||
|
||||
region.dstOffsets[1].x = qMax(1, w >> 1);
|
||||
@ -3391,16 +3393,16 @@ void QRhiVulkan::enqueueResourceUpdates(QVkCommandBuffer *cbD, QRhiResourceUpdat
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, origLayout,
|
||||
VK_ACCESS_TRANSFER_READ_BIT, origAccess,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, origStage,
|
||||
u.layer, 1,
|
||||
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,
|
||||
layer, 1,
|
||||
int(utexD->mipLevelCount) - 1, 1);
|
||||
}
|
||||
|
||||
}
|
||||
utexD->lastActiveFrameSlot = currentFrameSlot;
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,8 @@ void Window::customInit()
|
||||
d.releasePool << d.ubuf;
|
||||
|
||||
const QSize cubeMapSize(512, 512);
|
||||
d.tex = m_r->newTexture(QRhiTexture::RGBA8, cubeMapSize, 1, QRhiTexture::CubeMap);
|
||||
d.tex = m_r->newTexture(QRhiTexture::RGBA8, cubeMapSize, 1, QRhiTexture::CubeMap
|
||||
| QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips); // exercise mipmap generation as well
|
||||
d.releasePool << d.tex;
|
||||
d.tex->create();
|
||||
|
||||
@ -93,6 +94,8 @@ void Window::customInit()
|
||||
});
|
||||
d.initialUpdates->uploadTexture(d.tex, desc);
|
||||
|
||||
d.initialUpdates->generateMips(d.tex);
|
||||
|
||||
d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
|
||||
QRhiSampler::Repeat, QRhiSampler::Repeat);
|
||||
d.releasePool << d.sampler;
|
||||
|
Loading…
Reference in New Issue
Block a user