首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Vulkan生成mipmap

在Vulkan生成mipmap
EN

Stack Overflow用户
提问于 2016-06-12 09:12:39
回答 1查看 2.9K关注 0票数 6

我试图使用glGenerateMipmap()生成mipmap运行时(实现vkCmdBlitImage功能),但不理解这个过程。到目前为止,这是我的代码:

代码语言:javascript
复制
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级别图像,并且没有任何验证错误)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-12 10:01:13

每个mip级别都需要自己的形象吗?

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

它们应该如何初始化?当使用纹理数据的暂存缓冲区时,何时应该生成mipmap?

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

如果您只想从一个文件中加载它们,那么就不要使用blit了。创建一个暂存缓冲区(而不是图像),将纹理数据加载到其中,并从该缓冲区对图像执行vkCmdCopyBufferToImage操作。

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

有一件事可能是错误的(如果没有更多的代码,很难判断)是blit源代码中的mipLevel。你真的有一个来源有完整的mip链和复制mip的mip?

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37772540

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档