6

を使用して mipmaps ランタイム (glGenerateMipmap()機能を実装) を生成しようとしてvkCmdBlitImageいますが、プロセスがわかりません。これまでの私のコードは次のとおりです。

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 );
    }

各ミップ レベルには独自のイメージが必要ですか? どのように初期化する必要がありますか? テクスチャ データにステージング バッファを使用する場合、いつミップマップを生成する必要がありますか?

編集: 提案どおりに 1 つの画像のみを使用するようにコードを変更しましたが、現在は機能しているようです (RenderDoc テクスチャ ビューアで正しいミップ レベルの画像を確認でき、検証エラーは発生しません)。

4

1 に答える 1

4

各ミップ レベルには独自のイメージが必要ですか?

いいえ、ミップ レベルごとに個別の画像は必要ありません。テクスチャのイメージを作成する場合は、VkImageCreateInfo の mipLevels を設定するだけで済みます。

どのように初期化する必要がありますか? テクスチャ データにステージング バッファを使用する場合、いつミップマップを生成する必要がありますか?

これは、ミップに何を食べさせたいかによって大きく異なります。テクスチャ ファイル (静的ミップ レベル) からロードしたいだけですか、それとも実行時に生成する必要がありますか?

それらをファイルからロードしたいだけなら、まったく blit しないでください。ステージング バッファ (画像ではない) を作成し、テクスチャ データをそこにロードして、そのバッファから画像に対して vkCmdCopyBufferToImage を実行します。

しかし、もう少し詳細を追加していただけますか。実装に応じて重要になる可能性のある画像レイアウトの遷移は見られません。画像作成情報(フラグなど)に関する情報はなく、コードが実際に機能するかどうかは述べていません。

間違っている可能性があることの 1 つ (もう少しコードがないとわかりにくい) は、blit ソースの mipLevel です。完全なミップ チェーンを持ち、ミップごとにコピーするソースを本当に持っていますか?

于 2016-06-12T10:01:13.213 に答える