繁体   English   中英

在Vulkan中生成mipmap

[英]Generating mipmaps in Vulkan

我正在尝试使用vkCmdBlitImage生成mipmaps运行时(实现glGenerateMipmap()功能),但不了解该过程。 到目前为止,这是我的代码:

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级别图像,我没有得到任何验证错误)。

每个mip级别都需要自己的映像吗?

不,每个mip级别不需要单独的图像。 如果为纹理创建图像,则只需设置VkImageCreateInfo的mipLevels。

它们应该如何初始化? 在为纹理数据使用临时缓冲区时,我应该何时生成mipmap?

这在很大程度上取决于你想要给你的mips喂食什么。 您是否只想从纹理文件(静态mip级别)加载它们,还是需要在运行时生成它们?

如果您只想从文件中加载它们,请不要进行blit。 创建一个临时缓冲区(而不是图像),将纹理数据加载到其中,并从该缓冲区对您的图像执行vkCmdCopyBufferToImage。

但是,请你补充一些细节。 我没有看到任何可能至关重要的图像布局转换,具体取决于您所使用的实现,图像创建信息(例如标志)上没有信息,并且您没有说明您的代码是否实际有效。

有一点可能是错误的(很难说没有更多的代码)是你的blit源中的mipLevel。 你真的有一个拥有完整mip链并通过mip复制mip的源代码吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM