问题
The vulkan docs mention that moving image layouts in render passes (see VkAttachmentDescription
structure) is preferred compared to moving them using barriers (i.e. vkCmdPipelineBarrier
). I can understand that since the latter introduce sync points which constrain parallel execution.
Now consider a typical example: A transition from VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
to VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
. In this case the resource is going to be read in the shader, but in order to do that safely it is necessary to synchronize the writing of the color attachment with the reading in the shader. In other words we need to use a barrier anyway and moving the layout in the render pass doesn't seem to give any advantage at all.
Can somehow explain how all this works in detail? In which situations does one have a real advantage of moving layouts in render passes? Are there (practical) layout changes which do not require further synchronization?
回答1:
Firstly, you are not given a choice. The API forces you to provide finalLayout
, and intermediate VkAttachmentReference::layout
s. You can use vkCmdPipelineBarrier
inside the render pass conditionally (aka subpass self-dependency), but one of the rules is you are not allowed to change the layout of an attached image:
If a
VkImageMemoryBarrier
is used, the image and image subresource range specified in the barrier must be a subset of one of the image views used by the framebuffer in the current subpass. Additionally,oldLayout
must be equal tonewLayout
, and both thesrcQueueFamilyIndex
anddstQueueFamilyIndex
must beVK_QUEUE_FAMILY_IGNORED
.
So during a render pass, you can only change layout using the render pass mechanism, or you must be outside the render pass. That leaves only the "outside render pass" case to discuss:
Good way to think of a render pass is that it (potentially, based on platform) copies the resource (using loadOp
) to specialized memory, and when done copies it back (using storeOp
) back to general-purpose memory.
That being said, it is reasonable to assume you may get the layout transition to finalLayout
for free as part of the storeOp
. (And similarly the transition from initialLayout
to first VkAttachmentReference::layout
as part of the loadOp
.) So, it makes sense to have the layout transition as part of the renderpass, if possible\convenient enough.
来源:https://stackoverflow.com/questions/51401354/moving-image-layouts-with-barrier-or-renderpasses