Memory barriers are used to explicitly control access to buffer and image subresource ranges. Memory barriers are used to transfer ownership between queue families, change image layouts, and define availability and visibility operations. They explicitly define the access types and buffer and image subresource ranges that are included in the access scopes of a memory dependency that is created by a synchronization command that includes them.
Global memory barriers apply to memory accesses involving all memory objects that exist at the time of its execution.
The VkMemoryBarrier
structure is defined as:
typedef struct VkMemoryBarrier { VkStructureType sType; const void* pNext; VkAccessFlags srcAccessMask; VkAccessFlags dstAccessMask; } VkMemoryBarrier;
sType
is the type of this structure.
pNext
is NULL
or a pointer to an extension-specific structure.
srcAccessMask
defines a source access mask.
dstAccessMask
defines a destination access mask.
The first access scope is
limited to access types in the source access mask specified by srcAccessMask
.
The second access scope is
limited to access types in the destination access mask specified by dstAccessMask
.
Buffer memory barriers only apply to memory accesses involving a specific buffer range. That is, a memory dependency formed from an buffer memory barrier is scoped to access via the specified buffer range. Buffer memory barriers can also be used to define a queue family ownership transfer for the specified buffer range.
The VkBufferMemoryBarrier
structure is defined as:
typedef struct VkBufferMemoryBarrier { VkStructureType sType; const void* pNext; VkAccessFlags srcAccessMask; VkAccessFlags dstAccessMask; uint32_t srcQueueFamilyIndex; uint32_t dstQueueFamilyIndex; VkBuffer buffer; VkDeviceSize offset; VkDeviceSize size; } VkBufferMemoryBarrier;
sType
is the type of this structure.
pNext
is NULL
or a pointer to an extension-specific structure.
srcAccessMask
defines a source access mask.
dstAccessMask
defines a destination access mask.
srcQueueFamilyIndex
is the source queue family for a
queue family ownership transfer
dstQueueFamilyIndex
is the destination queue family for a
queue family ownership transfer
buffer
is a handle to the buffer whose backing memory is affected
by the barrier.
offset
is an offset in bytes into the backing memory for
buffer
; this is relative to the base offset as bound to the buffer
(see vkBindBufferMemory
).
size
is a size in bytes of the affected area of backing memory for
buffer
, or VK_WHOLE_SIZE
to use the range from offset
to the end of the buffer.
The first access scope is
limited to access to the memory backing the specified buffer range, via
access types in the source access mask
specified by srcAccessMask
.
The second access scope is
limited to access to the memory backing the specified buffer range, via
access types in the destination access mask specified by dstAccessMask
.
If srcQueueFamilyIndex
is not equal to dstQueueFamilyIndex
, and
srcQueueFamilyIndex
is equal to the current queue family, then the
memory barrier defines a queue family release operation for the specified buffer range, and the second
access scope includes no access, as if dstAccessMask
was 0
.
If dstQueueFamilyIndex
is not equal to srcQueueFamilyIndex
, and
dstQueueFamilyIndex
is equal to the current queue family, then the
memory barrier defines a queue family acquire operation for the specified buffer range, and the first
access scope includes no access, as if srcAccessMask
was 0
.
Image memory barriers only apply to memory accesses involving a specific image subresource range. That is, a memory dependency formed from an image memory barrier is scoped to access via the specified image subresource range. Image memory barriers can also be used to define image layout transitions or a queue family ownership transfer for the specified image subresource range.
The VkImageMemoryBarrier
structure is defined as:
typedef struct VkImageMemoryBarrier { VkStructureType sType; const void* pNext; VkAccessFlags srcAccessMask; VkAccessFlags dstAccessMask; VkImageLayout oldLayout; VkImageLayout newLayout; uint32_t srcQueueFamilyIndex; uint32_t dstQueueFamilyIndex; VkImage image; VkImageSubresourceRange subresourceRange; } VkImageMemoryBarrier;
sType
is the type of this structure.
pNext
is NULL
or a pointer to an extension-specific structure.
srcAccessMask
defines a source access mask.
dstAccessMask
defines a destination access mask.
oldLayout
is the old layout in an
image layout transition.
newLayout
is the new layout in an
image layout transition.
srcQueueFamilyIndex
is the source queue family for a
queue family ownership transfer
dstQueueFamilyIndex
is the destination queue family for a
queue family ownership transfer
image
is a handle to the image whose backing memory is affected by
the barrier.
subresourceRange
describes an area of the backing memory for
image
(see Section 11.5, “Image Views” for the description of
VkImageSubresourceRange
), as well as the set of image subresources
whose image layouts are modified.
The first access scope is
limited to access to the memory backing the specified image subresource
range, via access types in the source access mask specified by srcAccessMask
.
The second access scope is
limited to access to the memory backing the specified image subresource
range, via access types in the destination access mask specified by dstAccessMask
.
If srcQueueFamilyIndex
is not equal to dstQueueFamilyIndex
, and
srcQueueFamilyIndex
is equal to the current queue family, then the
memory barrier defines a queue family release operation for the specified image subresource range, and
the second access scope includes no access, as if dstAccessMask
was
0
.
If dstQueueFamilyIndex
is not equal to srcQueueFamilyIndex
, and
dstQueueFamilyIndex
is equal to the current queue family, then the
memory barrier defines a queue family acquire operation for the specified image subresource range, and
the first access scope includes no access, as if srcAccessMask
was
0
.
If oldLayout
is not equal to newLayout
, then the memory barrier
defines an image layout transition for the specified image subresource range.
Layout transitions that are performed via image memory barriers
automatically happen-after layout transitions previously submitted to the
same queue, and automatically happen-before layout transitions subsequently
submitted to the same queue; this includes layout transitions that occur as
part of a render pass instance, in both cases.
Resources created with a VkSharingMode
of
VK_SHARING_MODE_EXCLUSIVE
must have their ownership explicitly
transferred from one queue family to another in order to access their
content in a well-defined manner on a queue in a different queue family.
If memory dependencies are correctly expressed between uses of such a
resource between two queues in different families, but no ownership transfer
is defined, the contents of that resource are undefined for any read
accesses performed by the second queue family.
![]() | Note |
---|---|
If an application does not need the contents of a resource to remain valid when transferring from one queue family to another, then the ownership transfer should be skipped. |
A queue family ownership transfer consists of two distinct parts:
An application must ensure that these operations occur in the correct order by defining an execution dependency between them, e.g. using a semaphore.
A release operation is used to
release exclusive ownership of a range of a buffer or image subresource
range.
A release operation is defined by executing a
buffer memory barrier (for a
buffer range) or an image memory barrier (for an image subresource range), on a queue from the source queue
family.
The srcQueueFamilyIndex
parameter of the barrier must be set to the
source queue family index, and the dstQueueFamilyIndex
parameter to
the destination queue family index.
dstStageMask
is ignored for such a barrier, such that no visibility
operation is executed - the value of this mask does not affect the validity
of the barrier.
The release operation happens-after the availability operation.
An acquire operation is used
to acquire exclusive ownership of a range of a buffer or image subresource
range.
An acquire operation is defined by executing a
buffer memory barrier (for a
buffer range) or an image memory barrier (for an image subresource range), on a queue from the destination
queue family.
The srcQueueFamilyIndex
parameter of the barrier must be set to the
source queue family index, and the dstQueueFamilyIndex
parameter to
the destination queue family index.
srcStageMask
is ignored for such a barrier, such that no availability
operation is executed - the value of this mask does not affect the validity
of the barrier.
The acquire operation happens-before the visibility operation.
![]() | Note |
---|---|
Whilst it is not invalid to provide destination or source access masks for memory barriers used for release or acquire operations, respectively, they have no practical effect. Access after a release operation has undefined results, and so visibility for those accesses has no practical effect. Similarly, write access before an acquire operation will produce undefined results for future access, so availability of those writes has no practical use. In an earlier version of the specification, these were required to match on both sides - but this was subsequently relaxed. It is now recommended that these masks are simply set to 0. |
If the transfer is via an image memory barrier, and an
image layout transition is
desired, then the values of oldLayout
and newLayout
in the
release memory barrier must be equal to values of oldLayout
and
newLayout
in the acquire memory barrier.
Although the image layout transition is submitted twice, it will only be
executed once.
A layout transition specified in this way happens-after the release
operation and happens-before the acquire operation.
If the values of srcQueueFamilyIndex
and dstQueueFamilyIndex
are
equal, no ownership transfer is performed, and the barrier operates as if
they were both set to VK_QUEUE_FAMILY_IGNORED
.
Queue family ownership transfers may perform read and write accesses on all memory bound to the image subresource or buffer range, so applications must ensure that all memory writes have been made available before a queue family ownership transfer is executed. Available memory is automatically made visible to queue family release and acquire operations, and writes performed by those operations are automatically made available.
Once a queue family has acquired ownership of a buffer range or image
subresource range of an VK_SHARING_MODE_EXCLUSIVE
resource, its
contents are undefined to other queue families unless ownership is
transferred.
The contents of any portion of another resource which aliases memory that is
bound to the transferred buffer or image subresource range are undefined
after a release or acquire operation.