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.
Batches begin execution in the order they appear in pBindInfo, but
may complete out of order.
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.