簡體   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