Single usage VkImageMemoryBarrier?

Viewed 111

I've been learning vulkan and following vulkan-tutorial and right now I'm at the Texture mapping part. I'm loading an image and uploading it to the host memory, but I'm having trouble understanding the layout transitions and barriers.

Consider this (pseudo)code for loading and transitioning an image (inspired by this), which will be sampled in a fragment shader:

auto texture = loadTexture(filePath);
auto stagingBuffer = createStagingBuffer(texture.pixels, texture.size);

// Create image with: 
//   usage - VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT
//   properties - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
auto imageBuffer = createImage();

// -- begin single usage command buffer --
auto cb = beginCommandBuffer();

VkImageMemoryBarrier preCopyBarrier {
    // ...
    .image = imageBuffer.image,
    .srcAccessMask = 0,
    .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
    .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
    .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
    // ...
};

// PipelineBarrier (preCopyBarrier):
//   srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
//   dstStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT
//   imageMemoryBarrier = &preCopyBarrier
vkCmdPipelineBarrier(cb, ...);

// Copy stagingBuffer.buffer to imageBuffer.image
//   dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
vkCmdCopyBufferToImage(cb, ...);

VkImageMemoryBarrier postCopyBarrier {
    // ...
    .image = imageBuffer.image,
    .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
    .dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
    .oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
    .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
    // ...
};

// PipelineBarrier (postCopyBarrier):
//   srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT
//   dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
//   imageMemoryBarrier = &postCopyBarrier
vkCmdPipelineBarrier(cb, ...)

endAndSubmitCommandBuffer(cb);

The preCopyBarrier is there because of the vkCmdCopyBufferToImage(...) command and will be "used"/"activated" only once and that is during this command(?).

The postCopyBarrier is there because of the fact, that it will be sampled in the fragment shader, so the layout transition

VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL -> VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL

has to happen every single time a frame is rendered(? Please correct me, if I'm wrong).

But (assuming I'm correct, which I'm probably not) I'm having trouble wrapping my head around the fact, that I'm creating a preCopyBarrier, which will be used only once and postCopyBarrier, which will be used continuously. If I were to load for example 200 textures, I'd have a bunch of their single usage preCopyBarriers laying around. Isn't this a...waste?

This might be a stupid question and I'm probably missing/misunderstanding something important, but I feel like I shouldn't move on without understanding this concept correctly.

0 Answers
Related