使用vkCmdBlitImage为立方体贴图纹理生成mipmap

时间:2017-07-31 23:49:35

标签: vulkan

当我们动态生成mipmap时,VkImageBlit.dstOffsets和VkImageBlit.srcOffsets的参数应该是什么? 我是逐层进行的,对于每个mipmap级别,但在某个地方它出错了,大多数情况下我认为偏移。所以我有数据,其中所有六个面具有第0个mipmap级别。

for(int j=0; j< bufferCopyRegions.size(); j++) {

    for (int32_t i = 1; i < mipLevels; i++)
    {

        VkImageBlit imageBlit{};

        // Source
        imageBlit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
        imageBlit.srcSubresource.layerCount = 1;
        imageBlit.srcSubresource.mipLevel = 0;

        imageBlit.srcOffsets[1].x = bitmapInfos[j].width;  
        imageBlit.srcOffsets[1].y = bitmapInfos[j].height;  
        imageBlit.srcOffsets[1].z = 1;

        // Destination
        imageBlit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
        imageBlit.dstSubresource.layerCount = 1;
        imageBlit.dstSubresource.mipLevel = i;


        imageBlit.dstOffsets[1].x = int32_t(bitmapInfos[j].width >> (i) == 0 ? 1 : int32_t(bitmapInfos[j].width >> (i )));
        imageBlit.dstOffsets[1].y = int32_t(bitmapInfos[j].height >> (i) == 0 ? 1 : int32_t(bitmapInfos[j].height >> (i)));
        imageBlit.dstOffsets[1].z = 1;

        VkImageMemoryBarrier imageMemoryBarrier = {};
        imageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
        imageMemoryBarrier.pNext = NULL;
        imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
        imageMemoryBarrier.subresourceRange.baseMipLevel = i;
        imageMemoryBarrier.subresourceRange.levelCount = 1;
        imageMemoryBarrier.subresourceRange.baseArrayLayer = j;
        imageMemoryBarrier.subresourceRange.layerCount = 1;

        // change layout of current mip level to transfer dest
        setImageLayout(imageMemoryBarrier,
                       blitCmd,
                       image,
                       VK_IMAGE_ASPECT_COLOR_BIT,
                       VK_IMAGE_LAYOUT_UNDEFINED,
                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, imageMemoryBarrier.subresourceRange,
                       VK_PIPELINE_STAGE_TRANSFER_BIT,
                       VK_PIPELINE_STAGE_HOST_BIT);

        // Do blit operation from previous mip level
        vkCmdBlitImage(blitCmd, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image,
                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &imageBlit, VK_FILTER_LINEAR);


        setImageLayout(imageMemoryBarrier, blitCmd, image, VK_IMAGE_ASPECT_COLOR_BIT,
                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, imageMemoryBarrier.subresourceRange,
                       VK_PIPELINE_STAGE_HOST_BIT,
                       VK_PIPELINE_STAGE_TRANSFER_BIT);
    }
}

1 个答案:

答案 0 :(得分:1)

我看不到baseArrayLayerimageBlit.srcSubresource的{​​{1}}设置为imageBlit.dstSubresource。这可能是你的直接问题。

你的障碍对我来说也很糟糕。只有顶级mip需要与主机同步。但即使如此,j也应该,因为VK_PIPELINE_STAGE_HOST_BIT存在一个例外情况,即如果主机写入在被调用之前结束,它会隐式执行此类同步({{ 3}}并在6.9. Host Write Ordering Guarantees)的注释中提醒。