我試圖使用vkCmdBlitImage
生成mipmaps運行時(實現glGenerateMipmap()
功能),但不理解該過程。這是我的代碼到目前爲止:在Vulkan中生成mipmap
VkImageCreateInfo imageCreateInfo = {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.pNext = nullptr;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = format;
imageCreateInfo.mipLevels = mipLevels;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
imageCreateInfo.extent = { static_cast<std::uint32_t>(width), static_cast<std::uint32_t>(height), 1 };
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
err = vkCreateImage(GfxDeviceGlobal::device, &imageCreateInfo, nullptr, &image);
...
for (int i = 1; i < mipLevels; ++i)
{
const std::int32_t mipWidth = width >> i;
const std::int32_t mipHeight = height >> i;
VkImageBlit imageBlit = {};
imageBlit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlit.srcSubresource.baseArrayLayer = 0;
imageBlit.srcSubresource.layerCount = 1;
imageBlit.srcSubresource.mipLevel = 0;
imageBlit.srcOffsets[ 0 ] = { 0, 0, 0 };
imageBlit.srcOffsets[ 1 ] = { width, height, 1 };
imageBlit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
imageBlit.dstSubresource.baseArrayLayer = 0;
imageBlit.dstSubresource.layerCount = 1;
imageBlit.dstSubresource.mipLevel = i;
imageBlit.dstOffsets[ 0 ] = { 0, 0, 0 };
imageBlit.dstOffsets[ 1 ] = { mipWidth, mipHeight, 1 };
vkCmdBlitImage(texCmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &imageBlit, VK_FILTER_LINEAR);
}
是否每個mip級別都需要它自己的圖像?他們應該如何初始化?什麼時候在使用紋理數據的暫存緩衝區時應該生成mipmap?
編輯:我修改了代碼,只使用一個圖像的建議,它似乎現在工作(我可以在RenderDoc紋理查看器中看到正確的mip級別的圖像,我沒有得到任何驗證錯誤)。
src和dst圖像可以相同。爲此甚至應該。 ;每個圖像至少有1個mip級別([0]是基礎「紋理」)。把'i'弄糊塗到'i'是很奇怪的。 – krOoze