The APIs related to sparse resources are grouped into the following categories:
Some sparse-resource related features are reported and enabled in
VkPhysicalDeviceFeatures
.
These features must be supported and enabled on the VkDevice
object
before applications can use them.
See Physical Device Features for information on how to
get and set enabled device features, and for more detailed explanations of
these features.
sparseBinding
: Support for creating VkBuffer
and
VkImage
objects with the VK_BUFFER_CREATE_SPARSE_BINDING_BIT
and VK_IMAGE_CREATE_SPARSE_BINDING_BIT
flags, respectively.
sparseResidencyBuffer
: Support for creating VkBuffer
objects
with the VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
flag.
sparseResidencyImage2D
: Support for creating 2D single-sampled
VkImage
objects with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
.
sparseResidencyImage3D
: Support for creating 3D VkImage
objects with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
.
sparseResidency2Samples
: Support for creating 2D VkImage
objects with 2 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
.
sparseResidency4Samples
: Support for creating 2D VkImage
objects with 4 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
.
sparseResidency8Samples
: Support for creating 2D VkImage
objects with 8 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
.
sparseResidency16Samples
: Support for creating 2D VkImage
objects with 16 samples and VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
.
sparseResidencyAliased
: Support for creating VkBuffer
and
VkImage
objects with the VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
and VK_IMAGE_CREATE_SPARSE_ALIASED_BIT
flags, respectively.
Some features of the implementation are not possible to disable, and are
reported to allow applications to alter their sparse resource usage
accordingly.
These read-only capabilities are reported in the
VkPhysicalDeviceProperties
::sparseProperties
member, which is a
structure of type VkPhysicalDeviceSparseProperties
.
The VkPhysicalDeviceSparseProperties
structure is defined as:
typedef struct VkPhysicalDeviceSparseProperties { VkBool32 residencyStandard2DBlockShape; VkBool32 residencyStandard2DMultisampleBlockShape; VkBool32 residencyStandard3DBlockShape; VkBool32 residencyAlignedMipSize; VkBool32 residencyNonResidentStrict; } VkPhysicalDeviceSparseProperties;
residencyStandard2DBlockShape
is VK_TRUE
if the physical
device will access all single-sample 2D sparse resources using the
standard sparse image block shapes (based on image format), as described
in the Standard Sparse Image Block Shapes (Single Sample) table.
If this property is not supported the value returned in the
imageGranularity
member of the VkSparseImageFormatProperties
structure for single-sample 2D images is not required to match the
standard sparse image block dimensions listed in the table.
residencyStandard2DMultisampleBlockShape
is VK_TRUE
if the
physical device will access all multisample 2D sparse resources using
the standard sparse image block shapes (based on image format), as
described in the Standard Sparse Image Block Shapes (MSAA) table.
If this property is not supported, the value returned in the
imageGranularity
member of the VkSparseImageFormatProperties
structure for multisample 2D images is not required to match the
standard sparse image block dimensions listed in the table.
residencyStandard3DBlockShape
is VK_TRUE
if the physical
device will access all 3D sparse resources using the standard sparse
image block shapes (based on image format), as described in the
Standard Sparse Image Block Shapes (Single Sample) table.
If this property is not supported, the value returned in the
imageGranularity
member of the VkSparseImageFormatProperties
structure for 3D images is not required to match the standard sparse
image block dimensions listed in the table.
residencyAlignedMipSize
is VK_TRUE
if images with mip level
dimensions that are not integer multiples of the corresponding
dimensions of the sparse image block may be placed in the mip tail.
If this property is not reported, only mip levels with dimensions
smaller than the imageGranularity
member of the
VkSparseImageFormatProperties
structure will be placed in the mip
tail.
If this property is reported the implementation is allowed to return
VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT
in the flags
member of VkSparseImageFormatProperties
, indicating that mip level
dimensions that are not integer multiples of the corresponding
dimensions of the sparse image block will be placed in the mip tail.
residencyNonResidentStrict
specifies whether the physical device
can consistently access non-resident regions of a resource.
If this property is VK_TRUE
, access to non-resident regions of
resources will be guaranteed to return values as if the resource were
populated with 0; writes to non-resident regions will be discarded.
Given that certain aspects of sparse image support, including the sparse
image block dimensions, may be implementation-dependent,
vkGetPhysicalDeviceSparseImageFormatProperties
can be used to query
for sparse image format properties prior to resource creation.
This command is used to check whether a given set of sparse image parameters
is supported and what the sparse image block shape will be.
The VkSparseImageFormatProperties
structure is defined as:
typedef struct VkSparseImageFormatProperties { VkImageAspectFlags aspectMask; VkExtent3D imageGranularity; VkSparseImageFormatFlags flags; } VkSparseImageFormatProperties;
aspectMask
is a bitmask of VkImageAspectFlagBits
specifying
which aspects of the image the properties apply to.
imageGranularity
is the width, height, and depth of the sparse
image block in texels or compressed texel blocks.
flags
is a bitmask specifying additional information about the
sparse resource.
Bits which can be set include:
typedef enum VkSparseImageFormatFlagBits { VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002, VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004, } VkSparseImageFormatFlagBits;
VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT
is set, the image
uses a single mip tail region for all array layers.
VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT
is set, the first
mip level whose dimensions are not integer multiples of the
corresponding dimensions of the sparse image block begins the mip tail
region.
VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT
is set, the
image uses non-standard sparse image block dimensions, and the
imageGranularity
values do not match the standard sparse image
block dimensions for the given pixel format.
vkGetPhysicalDeviceSparseImageFormatProperties
returns an array of
VkSparseImageFormatProperties
.
Each element will describe properties for one set of image aspects that are
bound simultaneously in the image.
This is usually one element for each aspect in the image, but for
interleaved depth/stencil images there is only one element describing the
combined aspects.
void vkGetPhysicalDeviceSparseImageFormatProperties( VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties);
physicalDevice
is the physical device from which to query the
sparse image capabilities.
format
is the image format.
type
is the dimensionality of image.
samples
is the number of samples per pixel as defined in
VkSampleCountFlagBits
.
usage
is a bitmask describing the intended usage of the image.
tiling
is the tiling arrangement of the data elements in memory.
pPropertyCount
is a pointer to an integer related to the number of
sparse format properties available or queried, as described below.
pProperties
is either NULL
or a pointer to an array of
VkSparseImageFormatProperties
structures.
If pProperties
is NULL
, then the number of sparse format properties
available is returned in pPropertyCount
.
Otherwise, pPropertyCount
must point to a variable set by the user to
the number of elements in the pProperties
array, and on return the
variable is overwritten with the number of structures actually written to
pProperties
.
If pPropertyCount
is less than the number of sparse format properties
available, at most pPropertyCount
structures will be written.
If VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
is not supported for the given
arguments, pPropertyCount
will be set to zero upon return, and no data
will be written to pProperties
.
Multiple aspects are returned for depth/stencil images that are implemented
as separate planes by the implementation.
The depth and stencil data planes each have unique
VkSparseImageFormatProperties
data.
Depth/stencil images with depth and stencil data interleaved into a single
plane will return a single VkSparseImageFormatProperties
structure
with the aspectMask
set to VK_IMAGE_ASPECT_DEPTH_BIT
|
VK_IMAGE_ASPECT_STENCIL_BIT
.
Sparse resources require that one or more sparse feature flags be specified
(as part of the VkPhysicalDeviceFeatures
structure described
previously in the Physical Device Features
section) at CreateDevice time.
When the appropriate device features are enabled, the
VK_BUFFER_CREATE_SPARSE_*
and VK_IMAGE_CREATE_SPARSE_*
flags
can be used.
See vkCreateBuffer
and vkCreateImage
for details of the resource
creation APIs.
![]() | Note |
---|---|
Specifying |
Sparse resources have specific memory requirements related to binding sparse
memory.
These memory requirements are reported differently for VkBuffer
objects and VkImage
objects.
Buffers (both fully and partially resident) and fully-resident images can
be bound to memory using only the data from VkMemoryRequirements
.
For all sparse resources the VkMemoryRequirements
::alignment
member denotes both the bindable sparse block size in bytes and required
alignment of VkDeviceMemory
.
Partially resident images have a different method for binding memory.
As with buffers and fully resident images, the
VkMemoryRequirements
::alignment
field denotes the bindable
sparse block size in bytes for the image.
Requesting sparse memory requirements for VkImage
objects using
vkGetImageSparseMemoryRequirements
will return an array of one or more
VkSparseImageMemoryRequirements
structures.
Each structure describes the sparse memory requirements for a group of
aspects of the image.
The sparse image must have been created using the
VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
flag to retrieve valid sparse
image memory requirements.
The VkSparseImageMemoryRequirements
structure is defined as:
typedef struct VkSparseImageMemoryRequirements { VkSparseImageFormatProperties formatProperties; uint32_t imageMipTailFirstLod; VkDeviceSize imageMipTailSize; VkDeviceSize imageMipTailOffset; VkDeviceSize imageMipTailStride; } VkSparseImageMemoryRequirements;
formatProperties.aspectMask
is the set of aspects of the image
that this sparse memory requirement applies to.
This will usually have a single aspect specified.
However, depth/stencil images may have depth and stencil data
interleaved in the same sparse block, in which case both
VK_IMAGE_ASPECT_DEPTH_BIT
and VK_IMAGE_ASPECT_STENCIL_BIT
would be present.
formatProperties.imageGranularity
describes the dimensions of a
single bindable sparse image block in pixel units.
For aspect VK_IMAGE_ASPECT_METADATA_BIT
, all dimensions will be
zero pixels.
All metadata is located in the mip tail region.
formatProperties.flags
is a bitmask of
VkSparseImageFormatFlagBits
:
VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT
is set the image
uses a single mip tail region for all array layers.
VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT
is set the
dimensions of mip levels must be integer multiples of the
corresponding dimensions of the sparse image block for levels not
located in the mip tail.
VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT
is set the
image uses non-standard sparse image block dimensions.
The formatProperties.imageGranularity
values do not match the
standard sparse image block dimension corresponding to the image’s
pixel format.
imageMipTailFirstLod
is the first mip level at which image
subresources are included in the mip tail region.
imageMipTailSize
is the memory size (in bytes) of the mip tail
region.
If formatProperties.flags
contains
VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT
, this is the size of the
whole mip tail, otherwise this is the size of the mip tail of a single
array layer.
This value is guaranteed to be a multiple of the sparse block size in
bytes.
imageMipTailOffset
is the opaque memory offset used with
VkSparseImageOpaqueMemoryBindInfo
to bind the mip tail region(s).
imageMipTailStride
is the offset stride between each array-layer’s
mip tail, if formatProperties.flags
does not contain
VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT
(otherwise the value is
undefined).
To query sparse memory requirements for an image, call:
void vkGetImageSparseMemoryRequirements( VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements);
device
is the logical device that owns the image.
image
is the VkImage
object to get the memory requirements
for.
pSparseMemoryRequirementCount
is a pointer to an integer related
to the number of sparse memory requirements available or queried, as
described below.
pSparseMemoryRequirements
is either NULL
or a pointer to an
array of VkSparseImageMemoryRequirements
structures.
If pSparseMemoryRequirements
is NULL
, then the number of sparse
memory requirements available is returned in
pSparseMemoryRequirementCount
.
Otherwise, pSparseMemoryRequirementCount
must point to a variable set
by the user to the number of elements in the pSparseMemoryRequirements
array, and on return the variable is overwritten with the number of
structures actually written to pSparseMemoryRequirements
.
If pSparseMemoryRequirementCount
is less than the number of sparse
memory requirements available, at most pSparseMemoryRequirementCount
structures will be written.
If the image was not created with VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
then pSparseMemoryRequirementCount
will be set to zero and
pSparseMemoryRequirements
will not be written to.
![]() | Note |
---|---|
It is legal for an implementation to report a larger value in
|
Non-sparse resources are backed by a single physical allocation prior to
device use (via vkBindImageMemory
or vkBindBufferMemory
), and
their backing must not be changed.
On the other hand, sparse resources can be bound to memory non-contiguously
and these bindings can be altered during the lifetime of the resource.
![]() | Note |
---|---|
It is important to note that freeing a Implementations must ensure that no access to physical memory owned by the system or another process will occur in this scenario. In other words, accessing resources bound to freed memory may result in application termination, but must not result in system termination or in reading non-process-accessible memory. |
Sparse memory bindings execute on a queue that includes the
VK_QUEUE_SPARSE_BINDING_BIT
bit.
Applications must use synchronization primitives to
guarantee that other queues do not access ranges of memory concurrently with
a binding change.
Accessing memory in a range while it is being rebound results in undefined
behavior.
It is valid to access other ranges of the same resource while a bind
operation is executing.
![]() | Note |
---|---|
Implementations must provide a guarantee that simultaneously binding sparse blocks while another queue accesses those same sparse blocks via a sparse resource must not access memory owned by another process or otherwise corrupt the system. |
While some implementations may include VK_QUEUE_SPARSE_BINDING_BIT
support in queue families that also include graphics and compute support,
other implementations may only expose a
VK_QUEUE_SPARSE_BINDING_BIT
-only queue family.
In either case, applications must use synchronization primitives to explicitly request any ordering dependencies between sparse
memory binding operations and other graphics/compute/transfer operations, as
sparse binding operations are not automatically ordered against command
buffer execution, even within a single queue.
When binding memory explicitly for the VK_IMAGE_ASPECT_METADATA_BIT
the application must use the VK_SPARSE_MEMORY_BIND_METADATA_BIT
in
the VkSparseMemoryBind
::flags
field when binding memory.
Binding memory for metadata is done the same way as binding memory for the
mip tail, with the addition of the VK_SPARSE_MEMORY_BIND_METADATA_BIT
flag.
Binding the mip tail for any aspect must only be performed using
VkSparseImageOpaqueMemoryBindInfo
.
If formatProperties.flags
contains
VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT
, then it can be bound with
a single VkSparseMemoryBind
structure, with resourceOffset
=
imageMipTailOffset
and size
= imageMipTailSize
.
If formatProperties.flags
does not contain
VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT
then the offset for the mip
tail in each array layer is given as:
arrayMipTailOffset = imageMipTailOffset + arrayLayer * imageMipTailStride;
and the mip tail can be bound with layerCount
VkSparseMemoryBind
structures, each using size
= imageMipTailSize
and
resourceOffset
= arrayMipTailOffset
as defined above.
Sparse memory binding is handled by the following APIs and related data structures.
The VkSparseMemoryBind
structure is defined as:
typedef struct VkSparseMemoryBind { VkDeviceSize resourceOffset; VkDeviceSize size; VkDeviceMemory memory; VkDeviceSize memoryOffset; VkSparseMemoryBindFlags flags; } VkSparseMemoryBind;
resourceOffset
is the offset into the resource.
size
is the size of the memory region to be bound.
memory
is the VkDeviceMemory
object that the range of the
resource is bound to.
If memory
is VK_NULL_HANDLE
, the range is unbound.
memoryOffset
is the offset into the VkDeviceMemory
object to
bind the resource range to.
If memory
is VK_NULL_HANDLE
, this value is ignored.
flags
is a bitmask specifying usage of the binding operation.
Bits which can be set include:
typedef enum VkSparseMemoryBindFlagBits { VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, } VkSparseMemoryBindFlagBits;
VK_SPARSE_MEMORY_BIND_METADATA_BIT
indicates that the memory
being bound is only for the metadata aspect.
The binding range [resourceOffset
, resourceOffset
+
size
) has different constraints based on flags
.
If flags
contains VK_SPARSE_MEMORY_BIND_METADATA_BIT
, the
binding range must be within the mip tail region of the metadata aspect.
This metadata region is defined by:
imageMipTailSize
)
imageMipTailOffset
+ imageMipTailStride
×
n
and imageMipTailOffset
, imageMipTailSize
, and
imageMipTailStride
values are from the
VkSparseImageMemoryRequirements
corresponding to the metadata aspect
of the image, and n is a valid array layer index for the image,
imageMipTailStride
is considered to be zero for aspects where
VkSparseImageMemoryRequirements
::formatProperties.flags
contains
VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT
.
If flags
does not contain VK_SPARSE_MEMORY_BIND_METADATA_BIT
,
the binding range must be within the range
[0,VkMemoryRequirements
::size
).
Memory is bound to VkBuffer
objects created with the
VK_BUFFER_CREATE_SPARSE_BINDING_BIT
flag using the following
structure:
typedef struct VkSparseBufferMemoryBindInfo { VkBuffer buffer; uint32_t bindCount; const VkSparseMemoryBind* pBinds; } VkSparseBufferMemoryBindInfo;
buffer
is the VkBuffer
object to be bound.
bindCount
is the number of VkSparseMemoryBind
structures in
the pBinds
array.
pBinds
is a pointer to array of VkSparseMemoryBind
structures.
Memory is bound to opaque regions of VkImage
objects created with the
VK_IMAGE_CREATE_SPARSE_BINDING_BIT
flag using the following structure:
typedef struct VkSparseImageOpaqueMemoryBindInfo { VkImage image; uint32_t bindCount; const VkSparseMemoryBind* pBinds; } VkSparseImageOpaqueMemoryBindInfo;
image
is the VkImage
object to be bound.
bindCount
is the number of VkSparseMemoryBind
structures in
the pBinds
array.
pBinds
is a pointer to array of VkSparseMemoryBind
structures.
![]() | Note |
---|---|
This operation is normally used to bind memory to fully-resident sparse images or for mip tail regions of partially resident images. However, it can also be used to bind memory for the entire binding range of partially resident images. In case When |
![]() | editing-note |
---|---|
(Jon) The preceding NOTE refers to |
Memory can be bound to sparse image blocks of VkImage
objects created
with the VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
flag using the following
structure:
typedef struct VkSparseImageMemoryBindInfo { VkImage image; uint32_t bindCount; const VkSparseImageMemoryBind* pBinds; } VkSparseImageMemoryBindInfo;
image
is the VkImage
object to be bound
bindCount
is the number of VkSparseImageMemoryBind
structures in pBinds array
pBinds
is a pointer to array of VkSparseImageMemoryBind
structures
The VkSparseImageMemoryBind
structure is defined as:
typedef struct VkSparseImageMemoryBind { VkImageSubresource subresource; VkOffset3D offset; VkExtent3D extent; VkDeviceMemory memory; VkDeviceSize memoryOffset; VkSparseMemoryBindFlags flags; } VkSparseImageMemoryBind;
subresource
is the aspectMask and region of interest in the image.
offset
are the coordinates of the first texel within the image
subresource to bind.
extent
is the size in texels of the region within the image
subresource to bind.
The extent must be a multiple of the sparse image block dimensions,
except when binding sparse image blocks along the edge of an image
subresource it can instead be such that any coordinate of
offset
+ extent
equals the corresponding dimensions of
the image subresource.
memory
is the VkDeviceMemory
object that the sparse image
blocks of the image are bound to.
If memory
is VK_NULL_HANDLE
, the sparse image blocks are
unbound.
memoryOffset
is an offset into VkDeviceMemory
object.
If memory
is VK_NULL_HANDLE
, this value is ignored.
flags
are sparse memory binding flags.
To submit sparse binding operations to a queue, call:
VkResult vkQueueBindSparse( VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence);
queue
is the queue that the sparse binding operations will be
submitted to.
bindInfoCount
is the number of elements in the pBindInfo
array.
pBindInfo
is an array of VkBindSparseInfo
structures, each
specifying a sparse binding submission batch.
fence
is an optional handle to a fence to be signaled.
If fence
is not VK_NULL_HANDLE
, it defines a
fence signal operation.
vkQueueBindSparse
is a queue submission command, with each batch defined by an element of pBindInfo
as an
instance of the VkBindSparseInfo
structure.
Within a batch, a given range of a resource must not be bound more than once. Across batches, if a range is to be bound to one allocation and offset and then to another allocation and offset, then the application must guarantee (usually using semaphores) that the binding operations are executed in the correct order, as well as to order binding operations against the execution of command buffer submissions.
As no operation to vkQueueBindSparse
causes any pipeline stage to
access memory, synchronization primitives used in this command effectively
only define execution dependencies.
Additional information about fence and semaphore operation is described in the synchronization chapter.
The VkBindSparseInfo
structure is defined as:
typedef struct VkBindSparseInfo { VkStructureType sType; const void* pNext; uint32_t waitSemaphoreCount; const VkSemaphore* pWaitSemaphores; uint32_t bufferBindCount; const VkSparseBufferMemoryBindInfo* pBufferBinds; uint32_t imageOpaqueBindCount; const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; uint32_t imageBindCount; const VkSparseImageMemoryBindInfo* pImageBinds; uint32_t signalSemaphoreCount; const VkSemaphore* pSignalSemaphores; } VkBindSparseInfo;
sType
is the type of this structure.
pNext
is NULL
or a pointer to an extension-specific structure.
waitSemaphoreCount
is the number of semaphores upon which to wait
before executing the sparse binding operations for the batch.
pWaitSemaphores
is a pointer to an array of semaphores upon which
to wait on before the sparse binding operations for this batch begin
execution.
If semaphores to wait on are provided, they define a
semaphore wait operation.
bufferBindCount
is the number of sparse buffer bindings to perform
in the batch.
pBufferBinds
is a pointer to an array of
VkSparseBufferMemoryBindInfo
structures.
imageOpaqueBindCount
is the number of opaque sparse image bindings
to perform.
pImageOpaqueBinds
is a pointer to an array of
VkSparseImageOpaqueMemoryBindInfo
structures, indicating opaque
sparse image bindings to perform.
imageBindCount
is the number of sparse image bindings to perform.
pImageBinds
is a pointer to an array of
VkSparseImageMemoryBindInfo
structures, indicating sparse image
bindings to perform.
signalSemaphoreCount
is the number of semaphores to be signaled
once the sparse binding operations specified by the structure have
completed execution.
pSignalSemaphores
is a pointer to an array of semaphores which
will be signaled when the sparse binding operations for this batch have
completed execution.
If semaphores to be signaled are provided, they define a
semaphore signal operation.