Resources are initially created as virtual allocations with no backing memory. Device memory is allocated separately (see Section 10.2, “Device Memory”) and then associated with the resource. This association is done differently for sparse and non-sparse resources.
Resources created with any of the sparse creation flags are considered sparse resources. Resources created without these flags are non-sparse. The details on resource memory association for sparse resources is described in Chapter 28, Sparse Resources.
Non-sparse resources must be bound completely and contiguously to a single
VkDeviceMemory
object before the resource is passed as a parameter to
any of the following operations:
Once bound, the memory binding is immutable for the lifetime of the resource.
To determine the memory requirements for a buffer resource, call:
void vkGetBufferMemoryRequirements( VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements);
device
is the logical device that owns the buffer.
buffer
is the buffer to query.
pMemoryRequirements
points to an instance of the
VkMemoryRequirements
structure in which the memory requirements of
the buffer object are returned.
To determine the memory requirements for an image resource, call:
void vkGetImageMemoryRequirements( VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements);
device
is the logical device that owns the image.
image
is the image to query.
pMemoryRequirements
points to an instance of the
VkMemoryRequirements
structure in which the memory requirements of
the image object are returned.
The VkMemoryRequirements
structure is defined as:
typedef struct VkMemoryRequirements { VkDeviceSize size; VkDeviceSize alignment; uint32_t memoryTypeBits; } VkMemoryRequirements;
size
is the size, in bytes, of the memory allocation required for
the resource.
alignment
is the alignment, in bytes, of the offset within the
allocation required for the resource.
memoryTypeBits
is a bitmask and contains one bit set for every
supported memory type for the resource.
Bit i
is set if and only if the memory type i
in the
VkPhysicalDeviceMemoryProperties
structure for the physical device
is supported for the resource.
The implementation guarantees certain properties about the memory
requirements returned by vkGetBufferMemoryRequirements
and
vkGetImageMemoryRequirements
:
memoryTypeBits
member always contains at least one bit set.
buffer
is a VkBuffer
not created with the
VK_BUFFER_CREATE_SPARSE_BINDING_BIT
bit set, or if image
is
a VkImage
that was created with a VK_IMAGE_TILING_LINEAR
value in the tiling
member of the VkImageCreateInfo
structure passed to vkCreateImage
, then the memoryTypeBits
member always contains at least one bit set corresponding to a
VkMemoryType
with a propertyFlags
that has both the
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
bit and the
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
bit set.
In other words, mappable coherent memory can always be attached to
these objects.
memoryTypeBits
member always contains at least one bit set
corresponding to a VkMemoryType
with a propertyFlags
that
has the VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
bit set.
memoryTypeBits
member is identical for all VkBuffer
objects created with the same value for the flags
and usage
members in the VkBufferCreateInfo
structure passed to
vkCreateBuffer
.
Further, if usage1
and usage2
of type VkBufferUsageFlags
are such that the bits set in usage2
are a subset of the bits set
in usage1
, and they have the same flags
, then the bits set in
memoryTypeBits
returned for usage1
must be a subset of the
bits set in memoryTypeBits
returned for usage2
, for all
values of flags
.
alignment
member is a power of two.
alignment
member is identical for all VkBuffer
objects
created with the same combination of values for the usage
and
flags
members in the VkBufferCreateInfo
structure passed to
vkCreateBuffer
.
memoryTypeBits
member
is identical for all VkImage
objects created with the same
combination of values for the tiling
member, the
VK_IMAGE_CREATE_SPARSE_BINDING_BIT
bit of the flags
member,
and the VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
of the usage
member in the VkImageCreateInfo
structure passed to
vkCreateImage
.
memoryTypeBits
member is identical for all VkImage
objects created with the same
combination of values for the format
member, the tiling
member, the VK_IMAGE_CREATE_SPARSE_BINDING_BIT
bit of the
flags
member, and the
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
of the usage
member
in the VkImageCreateInfo
structure passed to vkCreateImage
.
VkImage
, the
memoryTypeBits
member must not refer to a VkMemoryType
with
a propertyFlags
that has the
VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
bit set if the
vkGetImageMemoryRequirements
::image
did not have
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
bit set in the usage
member of the VkImageCreateInfo
structure passed to
vkCreateImage
.
If the memory requirements are for a VkBuffer
, the
memoryTypeBits
member must not refer to a VkMemoryType
with
a propertyFlags
that has the
VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
bit set.
![]() | Note |
---|---|
The implication of this requirement is that lazily allocated memory is disallowed for buffers in all cases. |
To attach memory to a buffer object, call:
VkResult vkBindBufferMemory( VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset);
device
is the logical device that owns the buffer and memory.
buffer
is the buffer.
memory
is a VkDeviceMemory
object describing the device
memory to attach.
memoryOffset
is the start offset of the region of memory
which is to be bound to the buffer.
The number of bytes returned in the
VkMemoryRequirements
::size
member in memory
, starting
from memoryOffset
bytes, will be bound to the specified buffer.
To attach memory to an image object, call:
VkResult vkBindImageMemory( VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset);
device
is the logical device that owns the image and memory.
image
is the image.
memory
is the a VkDeviceMemory
object describing the device
memory to attach.
memoryOffset
is the start offset of the region of memory
which is to be bound to the image.
The number of bytes returned in the
VkMemoryRequirements
::size
member in memory
, starting
from memoryOffset
bytes, will be bound to the specified image.
Buffer-Image Granularity. There is an implementation-dependent limit, bufferImageGranularity
,
which specifies a page-like granularity at which buffer, linear image and
optimal image resources must be placed in adjacent memory locations to
avoid aliasing.
Two resources which do not satisfy this granularity requirement are said to
alias.
Linear image resource are images created with VK_IMAGE_TILING_LINEAR
and optimal image resources are those created with
VK_IMAGE_TILING_OPTIMAL
.
bufferImageGranularity
is specified in bytes, and must be a power of
two.
Implementations which do not require such an additional granularity may
report a value of one.
![]() | Note |
---|---|
|
Given resourceA at the lower memory offset and resourceB at the higher
memory offset in the same VkDeviceMemory
object, where one of the
resources is a buffer or a linear image and the other is an optimal image,
and the following:
resourceA.end = resourceA.memoryOffset + resourceA.size - 1 resourceA.endPage = resourceA.end & ~(bufferImageGranularity-1) resourceB.start = resourceB.memoryOffset resourceB.startPage = resourceB.start & ~(bufferImageGranularity-1)
The following property must hold:
resourceA.endPage < resourceB.startPage
That is, the end of the first resource (A) and the beginning of the second
resource (B) must be on separate “pages” of size
bufferImageGranularity
.
bufferImageGranularity
may be different than the physical page size
of the memory heap.
This restriction is only needed when a buffer or a linear image is at
adjacent memory location with an optimal image and both will be used
simultaneously.
Adjacent buffers' or adjacent images' memory ranges can be closer than
bufferImageGranularity
, provided they meet the alignment
requirement for the objects in question.
Sparse block size in bytes and sparse image and buffer memory alignments
must all be multiples of the bufferImageGranularity
.
Therefore, memory bound to sparse resources naturally satisfies the
bufferImageGranularity
.