Resource Creation
Vulkan supports two primary resource types: buffers and images. Resources are views of memory with associated formatting and dimensionality. Buffers provide access to raw arrays of bytes, whereas images can be multidimensional and may have associated metadata.
Other resource types, such as acceleration structures and micromaps use buffers as the backing store for opaque data structures.
Buffers
Buffer Views
Buffer View Format Features
Valid uses of a VkBufferView may depend on the buffer view’s format features, defined below. Such constraints are documented in the affected valid usage statement.
- If Vulkan 1.3 is supported or the VK_KHR_format_feature_flags2
extension is supported, then the buffer view’s set of format features
is the value of VkFormatProperties3::
bufferFeatures
found by calling vkGetPhysicalDeviceFormatProperties2 on the sameformat
as VkBufferViewCreateInfo::format
.
Images
Image Format Features
Valid uses of a VkImage may depend on the image’s format features, defined below. Such constraints are documented in the affected valid usage statement.
- If the image was created with
VK_IMAGE_TILING_LINEAR
, then its set of format features is the value of VkFormatProperties::linearTilingFeatures
found by calling vkGetPhysicalDeviceFormatProperties on the sameformat
as VkImageCreateInfo::format
. - If the image was created with
VK_IMAGE_TILING_OPTIMAL
, but without an Android hardware buffer external format, or a QNX Screen Buffer external format or an VkBufferCollectionImageCreateInfoFUCHSIA, then its set of format features is the value of VkFormatProperties::optimalTilingFeatures
found by calling vkGetPhysicalDeviceFormatProperties on the sameformat
as VkImageCreateInfo::format
. - If the image was created with an
Android
hardware buffer external format, then its set of format features is
the value of
VkAndroidHardwareBufferFormatPropertiesANDROID::
formatFeatures
found by calling vkGetAndroidHardwareBufferPropertiesANDROID on the Android hardware buffer that was imported to the VkDeviceMemory to which the image is bound. - If the image was created with an
QNX Screen buffer
external format, then its set of format features is the value of
VkScreenBufferFormatPropertiesQNX::
formatFeatures
found by calling vkGetScreenBufferPropertiesQNX on the QNX Screen buffer that was imported to the VkDeviceMemory to which the image is bound. - If the image was created with
VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT
, then:- The image’s DRM format modifier is the value of
VkImageDrmFormatModifierPropertiesEXT::
drmFormatModifier
found by calling vkGetImageDrmFormatModifierPropertiesEXT. - Let
VkDrmFormatModifierPropertiesListEXT::
pDrmFormatModifierProperties
be the array found by calling vkGetPhysicalDeviceFormatProperties2 on the sameformat
as VkImageCreateInfo::format
. - Let
VkDrmFormatModifierPropertiesEXT prop
be the array element whosedrmFormatModifier
member is the value of the image’s DRM format modifier. - Then the image’s set of format features is the value of
prop
::drmFormatModifierTilingFeatures
.
- The image’s DRM format modifier is the value of
VkImageDrmFormatModifierPropertiesEXT::
Corner-Sampled Images
A corner-sampled image is an image where unnormalized texel coordinates are centered on integer values rather than half-integer values.
A corner-sampled image has a number of differences compared to conventional texture image:
- Texels are centered on integer coordinates. See Unnormalized Texel Coordinate Operations
- Normalized coordinates are scaled using coord × (dim - 1) rather than coord × dim, where dim is the size of one dimension of the image. See normalized texel coordinate transform.
- Partial derivatives are scaled using coord × (dim - 1) rather than coord × dim. See Scale Factor Operation.
- Calculation of the next higher LOD size goes according to ⌈dim / 2⌉ rather than ⌊dim / 2⌋. See Image Mip Level Sizing.
- The minimum level size is 2x2 for 2D images and 2x2x2 for 3D images. See Image Mip Level Sizing.
Corner-sampling is only supported for 2D and 3D images.
When sampling a corner-sampled image, the sampler addressing mode must be
VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
.
Corner-sampled images are not supported as cube maps or depth/stencil
images.
Image Mip Level Sizing
A complete mipmap chain is the full set of mip levels, from the largest mip level provided, down to the minimum mip level size.
Conventional Images
For conventional images, the dimensions of each successive mip level, n+1, are:
width
n+1 = max(⌊width
n/2⌋, 1)height
n+1 = max(⌊height
n/2⌋, 1)depth
n+1 = max(⌊depth
n/2⌋, 1)
where width
n, height
n, and depth
n
are the dimensions of the next larger mip level, n.
The minimum mip level size is:
- 1 for one-dimensional images,
- 1x1 for two-dimensional images, and
- 1x1x1 for three-dimensional images.
The number of levels in a complete mipmap chain is:
- ⌊log2(max(
width
0,height
0,depth
0))⌋ + 1
where width
0, height
0, and depth
0
are the dimensions of the largest (most detailed) mip level, 0
.
Corner-Sampled Images
For corner-sampled images, the dimensions of each successive mip level, n+1, are:
width
n+1 = max(⌈width
n/2⌉, 2)height
n+1 = max(⌈height
n/2⌉, 2)depth
n+1 = max(⌈depth
n/2⌉, 2)
where width
n, height
n, and depth
n
are the dimensions of the next larger mip level, n.
The minimum mip level size is:
- 2x2 for two-dimensional images, and
- 2x2x2 for three-dimensional images.
The number of levels in a complete mipmap chain is:
- ⌈log2(max(
width
0,height
0,depth
0))⌉
where width
0, height
0, and depth
0
are the dimensions of the largest (most detailed) mip level, 0
.
Image Layouts
Images are stored in implementation-dependent opaque layouts in memory.
Each layout has limitations on what kinds of operations are supported for
image subresources using the layout.
At any given time, the data representing an image subresource in memory
exists in a particular layout which is determined by the most recent layout
transition that was performed on that image subresource.
Applications have control over which layout each image subresource uses, and
can transition an image subresource from one layout to another.
Transitions can happen with an image memory barrier, included as part of a
vkCmdPipelineBarrier or a vkCmdWaitEvents command buffer command
(see Image Memory Barriers), or as part of a subpass
dependency within a render pass (see VkSubpassDependency
).
Image layout is per-image subresource.
Separate image subresources of the same image can be in different layouts
at the same time, with the exception that depth and stencil aspects of a
given image subresource can only be in different layouts if the
separateDepthStencilLayouts
feature is enabled.
Each layout may offer optimal performance for a specific usage of image
memory.
For example, an image with a layout of
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
may provide optimal
performance for use as a color attachment, but be unsupported for use in
transfer commands.
Applications can transition an image subresource from one layout to another
in order to achieve optimal performance when the image subresource is used
for multiple kinds of operations.
After initialization, applications need not use any layout other than the
general layout, though this may produce suboptimal performance on some
implementations.
Upon creation, all image subresources of an image are initially in the same
layout, where that layout is selected by the
VkImageCreateInfo
::initialLayout
member.
The initialLayout
must be either VK_IMAGE_LAYOUT_UNDEFINED
or
VK_IMAGE_LAYOUT_PREINITIALIZED
.
If it is VK_IMAGE_LAYOUT_PREINITIALIZED
, then the image data can be
preinitialized by the host while using this layout, and the transition away
from this layout will preserve that data.
If it is VK_IMAGE_LAYOUT_UNDEFINED
, then the contents of the data are
considered to be undefined:, and the transition away from this layout is not
guaranteed to preserve that data.
For either of these initial layouts, any image subresources must be
transitioned to another layout before they are accessed by the device.
Host access to image memory is only well-defined for
linear images and for image subresources of
those images which are currently in either the
VK_IMAGE_LAYOUT_PREINITIALIZED
or VK_IMAGE_LAYOUT_GENERAL
layout.
Calling vkGetImageSubresourceLayout for a linear image returns a
subresource layout mapping that is valid for either of those image layouts.
Image Layout Matching Rules
At the time that any command buffer command accessing an image executes on any queue, the layouts of the image subresources that are accessed must all match exactly the layout specified via the API controlling those accesses, except in case of accesses to an image with a depth/stencil format performed through descriptors referring to only a single aspect of the image, where the following relaxed matching rules apply:
- Descriptors referring just to the depth aspect of a depth/stencil image
only need to match in the image layout of the depth aspect, thus
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
andVK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL
are considered to match. - Descriptors referring just to the stencil aspect of a depth/stencil
image only need to match in the image layout of the stencil aspect, thus
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
andVK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL
are considered to match.
When performing a layout transition on an image subresource, the old layout
value must either equal the current layout of the image subresource (at the
time the transition executes), or else be VK_IMAGE_LAYOUT_UNDEFINED
(implying that the contents of the image subresource need not be preserved).
The new layout used in a transition must not be
VK_IMAGE_LAYOUT_UNDEFINED
or VK_IMAGE_LAYOUT_PREINITIALIZED
.
The image layout of each image subresource of a depth/stencil image created
with VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
is
dependent on the last sample locations used to render to the image
subresource as a depth/stencil attachment, thus applications must provide
the same sample locations that were last used to render to the given image
subresource whenever a layout transition of the image subresource happens,
otherwise the contents of the depth aspect of the image subresource become
undefined:.
In addition, depth reads from a depth/stencil attachment referring to an
image subresource range of a depth/stencil image created with
VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
using
different sample locations than what have been last used to perform depth
writes to the image subresources of the same image subresource range return
undefined: values.
Similarly, depth writes to a depth/stencil attachment referring to an image
subresource range of a depth/stencil image created with
VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT
using
different sample locations than what have been last used to perform depth
writes to the image subresources of the same image subresource range make
the contents of the depth aspect of those image subresources undefined:.
Image Views
Image View Format Features
Valid uses of a VkImageView may depend on the image view’s format features, defined below. Such constraints are documented in the affected valid usage statement.
- If Vulkan 1.3 is supported or the VK_KHR_format_feature_flags2
extension is supported, and VkImageViewCreateInfo::
image
was created withVK_IMAGE_TILING_LINEAR
, then the image view’s set of format features is the value of VkFormatProperties3::linearTilingFeatures
found by calling vkGetPhysicalDeviceFormatProperties2 on the sameformat
as VkImageViewCreateInfo::format
. - If Vulkan 1.3 is not supported and the
VK_KHR_format_feature_flags2 extension is not supported, and
VkImageViewCreateInfo::
image
was created withVK_IMAGE_TILING_LINEAR
, then the image view’s set of format features is the union of the value of VkFormatProperties::linearTilingFeatures
found by calling vkGetPhysicalDeviceFormatProperties on the sameformat
as VkImageViewCreateInfo::format
, with:VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT
if the format is a depth/stencil format and the image view features also containVK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT
.VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT
if the format is one of the extended storage formats andshaderStorageImageReadWithoutFormat
is enabled on the device.VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT
if the format is one of the extended storage formats andshaderStorageImageWriteWithoutFormat
is enabled on the device.
- If Vulkan 1.3 is supported or the VK_KHR_format_feature_flags2
extension is supported, and VkImageViewCreateInfo::
image
was created withVK_IMAGE_TILING_OPTIMAL
, but without an Android hardware buffer external format, or a QNX Screen buffer external format, then the image view’s set of format features is the value of VkFormatProperties::optimalTilingFeatures
or VkFormatProperties3::optimalTilingFeatures
found by calling vkGetPhysicalDeviceFormatProperties or vkGetPhysicalDeviceImageFormatProperties2 on the sameformat
as VkImageViewCreateInfo::format
. - If Vulkan 1.3 is not supported and the
VK_KHR_format_feature_flags2 extension is not supported, and
VkImageViewCreateInfo::
image
was created withVK_IMAGE_TILING_OPTIMAL
, but without an Android hardware buffer external format, or a QNX Screen buffer external format, then the image view’s set of format features is the union of the value of VkFormatProperties::optimalTilingFeatures
found by calling vkGetPhysicalDeviceFormatProperties on the sameformat
as VkImageViewCreateInfo::format
, with:VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT
if the format is a depth/stencil format and the image view features also containVK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT
.VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT
if the format is one of the extended storage formats andshaderStorageImageReadWithoutFormat
is enabled on the device.VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT
if the format is one of the extended storage formats andshaderStorageImageWriteWithoutFormat
is enabled on the device.
- If VkImageViewCreateInfo::
image
was created with an Android hardware buffer external format, then the image views’s set of format features is the value of VkAndroidHardwareBufferFormatPropertiesANDROID::formatFeatures
found by calling vkGetAndroidHardwareBufferPropertiesANDROID on the Android hardware buffer that was imported to the VkDeviceMemory to which the VkImageViewCreateInfo::image
is bound. - If VkImageViewCreateInfo::
image
was created with a QNX Screen buffer external format, then the image views’s set of format features is the value of VkScreenBufferFormatPropertiesQNX::formatFeatures
found by calling vkGetScreenBufferPropertiesQNX on the QNX Screen buffer that was imported to the VkDeviceMemory to which the VkImageViewCreateInfo::image
is bound. - If VkImageViewCreateInfo::
image
was created with a chained VkBufferCollectionImageCreateInfoFUCHSIA, then the image view’s set of format features is the value of VkBufferCollectionPropertiesFUCHSIA::formatFeatures
found by calling vkGetBufferCollectionPropertiesFUCHSIA on the buffer collection passed as VkBufferCollectionImageCreateInfoFUCHSIA::collection
when the image was created. - If VkImageViewCreateInfo::
image
was created withVK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT
, then:- The image’s DRM format modifier is the value of
VkImageDrmFormatModifierPropertiesEXT::
drmFormatModifier
found by calling vkGetImageDrmFormatModifierPropertiesEXT. - Let
VkDrmFormatModifierPropertiesListEXT::
pDrmFormatModifierProperties
be the array found by calling vkGetPhysicalDeviceFormatProperties2 on the sameformat
as VkImageViewCreateInfo::format
. - Let
VkDrmFormatModifierPropertiesEXT prop
be the array element whosedrmFormatModifier
member is the value of the image’s DRM format modifier. - Then the image view’s set of format features is
prop
::drmFormatModifierTilingFeatures
.
- The image’s DRM format modifier is the value of
VkImageDrmFormatModifierPropertiesEXT::
Acceleration Structures
Micromaps
Resource Memory Association
Resources are initially created as virtual allocations with no backing memory. Device memory is allocated separately (see 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 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:
- creating image or buffer views
- updating descriptor sets
- recording commands in a command buffer
Once bound, the memory binding is immutable for the lifetime of the resource.
In a logical device representing more than one physical device, buffer and image resources exist on all physical devices but can be bound to memory differently on each. Each such replicated resource is an instance of the resource. For sparse resources, each instance can be bound to memory arbitrarily differently. For non-sparse resources, each instance can either be bound to the local or a peer instance of the memory, or for images can be bound to rectangular regions from the local and/or peer instances. When a resource is used in a descriptor set, each physical device interprets the descriptor according to its own instance’s binding to memory.
There are no new copy commands to transfer data between physical devices. Instead, an application can create a resource with a peer mapping and use it as the source or destination of a transfer command executed by a single physical device to copy the data from one physical device to another.
The precise size of images that will be bound to external Android hardware
buffer memory is unknown until the memory has been imported or allocated, so
applications must not call vkGetImageMemoryRequirements or
vkGetImageMemoryRequirements2 with such a VkImage before it has
been bound to memory.
For this reason, applications also must not call
vkGetDeviceImageMemoryRequirements with a VkImageCreateInfo
describing an external Android hardware buffer.
When importing Android hardware buffer memory, the allocationSize
can
be determined by calling vkGetAndroidHardwareBufferPropertiesANDROID.
When allocating new memory for a VkImage that can be exported to an
Android hardware buffer, the memory’s allocationSize
must be zero;
the actual size will be determined by the dedicated image’s parameters.
After the memory has been allocated, the amount of space allocated from the
memory’s heap can be obtained by getting the image’s memory requirements or
by calling vkGetAndroidHardwareBufferPropertiesANDROID with the
Android hardware buffer exported from the memory.
When allocating new memory for a VkBuffer that can be exported to an Android hardware buffer an application may still call vkGetBufferMemoryRequirements or vkGetBufferMemoryRequirements2 with VkBuffer before it has been bound to memory.
If the resource being queried was created with the
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT
,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT
, or
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT
external memory
handle type, the value of size
has no meaning and should be ignored.
The implementation guarantees certain properties about the memory requirements returned by vkGetBufferMemoryRequirements2, vkGetImageMemoryRequirements2, vkGetDeviceBufferMemoryRequirements, vkGetDeviceImageMemoryRequirements, vkGetBufferMemoryRequirements and vkGetImageMemoryRequirements:
- The
memoryTypeBits
member always contains at least one bit set. - If
buffer
is aVkBuffer
not created with theVK_BUFFER_CREATE_SPARSE_BINDING_BIT
orVK_BUFFER_CREATE_PROTECTED_BIT
bits set, or ifimage
is a linear image that was not created with theVK_IMAGE_CREATE_PROTECTED_BIT
bit set, then thememoryTypeBits
member always contains at least one bit set corresponding to aVkMemoryType
with apropertyFlags
that has both theVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
bit and theVK_MEMORY_PROPERTY_HOST_COHERENT_BIT
bit set. In other words, mappable coherent memory can always be attached to these objects. - If
buffer
was created with VkExternalMemoryBufferCreateInfo::handleTypes
set to0
orimage
was created with VkExternalMemoryImageCreateInfo::handleTypes
set to0
, thememoryTypeBits
member always contains at least one bit set corresponding to aVkMemoryType
with apropertyFlags
that has theVK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
bit set. - The
memoryTypeBits
member is identical for allVkBuffer
objects created with the same value for theflags
andusage
members in the VkBufferCreateInfo structure and thehandleTypes
member of the VkExternalMemoryBufferCreateInfo structure passed to vkCreateBuffer. Further, ifusage1
andusage2
of type VkBufferUsageFlags are such that the bits set inusage2
are a subset of the bits set inusage1
, and they have the sameflags
and VkExternalMemoryBufferCreateInfo::handleTypes
, then the bits set inmemoryTypeBits
returned forusage1
must be a subset of the bits set inmemoryTypeBits
returned forusage2
, for all values offlags
. - The
alignment
member is a power of two. - The
alignment
member is identical for allVkBuffer
objects created with the same combination of values for theusage
andflags
members in the VkBufferCreateInfo structure passed to vkCreateBuffer. - If the
maintenance4
feature is enabled, then thealignment
member is identical for allVkImage
objects created with the same combination of values for theflags
,imageType
,format
,extent
,mipLevels
,arrayLayers
,samples
,tiling
andusage
members in the VkImageCreateInfo structure passed to vkCreateImage. - The
alignment
member satisfies the buffer descriptor offset alignment requirements associated with theVkBuffer
’susage
:- If
usage
includedVK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
orVK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
,alignment
must be an integer multiple ofVkPhysicalDeviceLimits
::minTexelBufferOffsetAlignment
. - If
usage
includedVK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
,alignment
must be an integer multiple ofVkPhysicalDeviceLimits
::minUniformBufferOffsetAlignment
. - If
usage
includedVK_BUFFER_USAGE_STORAGE_BUFFER_BIT
,alignment
must be an integer multiple ofVkPhysicalDeviceLimits
::minStorageBufferOffsetAlignment
.
- If
- For images created with a color format, the
memoryTypeBits
member is identical for allVkImage
objects created with the same combination of values for thetiling
member, theVK_IMAGE_CREATE_SPARSE_BINDING_BIT
bit of theflags
member, theVK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT
bit of theflags
member, theVK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT
bit of theusage
member if the VkPhysicalDeviceHostImageCopyPropertiesEXT::identicalMemoryTypeRequirements
property isVK_FALSE
,handleTypes
member of VkExternalMemoryImageCreateInfo, and theVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
of theusage
member in the VkImageCreateInfo structure passed to vkCreateImage. - For images created with a depth/stencil format, the
memoryTypeBits
member is identical for allVkImage
objects created with the same combination of values for theformat
member, thetiling
member, theVK_IMAGE_CREATE_SPARSE_BINDING_BIT
bit of theflags
member, theVK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT
bit of theflags
member, theVK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT
bit of theusage
member if the VkPhysicalDeviceHostImageCopyPropertiesEXT::identicalMemoryTypeRequirements
property isVK_FALSE
,handleTypes
member of VkExternalMemoryImageCreateInfo, and theVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
of theusage
member in the VkImageCreateInfo structure passed to vkCreateImage. - If the memory requirements are for a
VkImage
, thememoryTypeBits
member must not refer to aVkMemoryType
with apropertyFlags
that has theVK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
bit set if theimage
did not haveVK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
bit set in theusage
member of the VkImageCreateInfo structure passed to vkCreateImage. - If the memory requirements are for a
VkBuffer
, thememoryTypeBits
member must not refer to aVkMemoryType
with apropertyFlags
that has theVK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
bit set.The implication of this requirement is that lazily allocated memory is disallowed for buffers in all cases.
- The
size
member is identical for allVkBuffer
objects created with the same combination of creation parameters specified in VkBufferCreateInfo and itspNext
chain. - The
size
member is identical for allVkImage
objects created with the same combination of creation parameters specified in VkImageCreateInfo and itspNext
chain.This, however, does not imply that they interpret the contents of the bound memory identically with each other. That additional guarantee, however, can be explicitly requested using
VK_IMAGE_CREATE_ALIAS_BIT
. - If the
maintenance4
feature is enabled, these additional guarantees apply:- For a
VkBuffer
, thesize
memory requirement is never greater than that of anotherVkBuffer
created with a greater or equalsize
specified in VkBufferCreateInfo, all other creation parameters being identical. - For a
VkBuffer
, thesize
memory requirement is never greater than the result of aligning VkBufferCreateInfo::size
with thealignment
memory requirement. - For a VkImage, the
size
memory requirement is never greater than that of another VkImage created with a greater or equal value in each ofextent.width
,extent.height
, andextent.depth
; all other creation parameters being identical. - The memory requirements returned by
vkGetDeviceBufferMemoryRequirements are identical to those that
would be returned by vkGetBufferMemoryRequirements2 if it were
called with a
VkBuffer
created with the same VkBufferCreateInfo values. - The memory requirements returned by
vkGetDeviceImageMemoryRequirements are identical to those that
would be returned by vkGetImageMemoryRequirements2 if it were
called with a
VkImage
created with the same VkImageCreateInfo values.
- For a
Buffer-Image Granularity
The implementation-dependent limit bufferImageGranularity
specifies a page-like granularity at which
linear and non-linear resources must be placed in adjacent memory locations
to avoid aliasing.
Two resources which do not satisfy this granularity requirement are said to
alias.
bufferImageGranularity
is specified in bytes, and must be a power of
two.
Implementations which do not impose a granularity restriction may report a
bufferImageGranularity
value of one.
Despite its name, bufferImageGranularity
is really a granularity
between linear
and non-linear
resources.
Given resourceA at the lower memory offset and resourceB at the higher
memory offset in the same VkDeviceMemory
object, where one resource is
linear and the other is non-linear (as defined in the
Glossary), 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 linear resource and a non-linear
resource are adjacent in memory and will be used simultaneously.
The memory ranges of adjacent resources 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
.
Resource Sharing Mode
External Resource Sharing
Resources should only be accessed in the Vulkan instance that has exclusive
ownership of their underlying memory.
Only one Vulkan instance has exclusive ownership of a resource’s underlying
memory at a given time, regardless of whether the resource was created using
VK_SHARING_MODE_EXCLUSIVE
or VK_SHARING_MODE_CONCURRENT
.
Applications can transfer ownership of a resource’s underlying memory only
if the memory has been imported from or exported to another instance or
external API using external memory handles.
The semantics for transferring ownership outside of the instance are similar
to those used for transferring ownership of VK_SHARING_MODE_EXCLUSIVE
resources between queues, and is also accomplished using
VkBufferMemoryBarrier or VkImageMemoryBarrier operations.
To make the contents of the underlying memory accessible in the destination
instance or API, applications must
- Release exclusive ownership from the source instance or API.
- Ensure the release operation has completed using semaphores or fences.
- Acquire exclusive ownership in the destination instance or API
Unlike queue family ownership transfers, the destination instance or API is
not specified explicitly when releasing ownership, nor is the source
instance or API specified when acquiring ownership.
Instead, the image or memory barrier’s dstQueueFamilyIndex
or
srcQueueFamilyIndex
parameters are set to the reserved queue family
index VK_QUEUE_FAMILY_EXTERNAL
or VK_QUEUE_FAMILY_FOREIGN_EXT
to represent the external destination or source respectively.
Binding a resource to a memory object shared between multiple Vulkan instances or other APIs does not change the ownership of the underlying memory. The first entity to access the resource implicitly acquires ownership. An entity can also implicitly take ownership from another entity in the same way without an explicit ownership transfer. However, taking ownership in this way has the effect that the contents of the underlying memory are undefined:.
Accessing a resource backed by memory that is owned by a particular instance
or API has the same semantics as accessing a VK_SHARING_MODE_EXCLUSIVE
resource, with one exception: Implementations must ensure layout
transitions performed on one member of a set of identical subresources of
identical images that alias the same range of an underlying memory object
affect the layout of all the subresources in the set.
As a corollary, writes to any image subresources in such a set must not
make the contents of memory used by other subresources in the set
undefined:.
An application can define the content of a subresource of one image by
performing device writes to an identical subresource of another image
provided both images are bound to the same region of external memory.
Applications may also add resources to such a set after the content of the
existing set members has been defined without making the content undefined:
by creating a new image with the initial layout
VK_IMAGE_LAYOUT_UNDEFINED
and binding it to the same region of
external memory as the existing images.
Because layout transitions apply to all identical images aliasing the same region of external memory, the actual layout of the memory backing a new image as well as an existing image with defined content will not be undefined:. Such an image is not usable until it acquires ownership of its memory from the existing owner. Therefore, the layout specified as part of this transition will be the true initial layout of the image. The undefined: layout specified when creating it is a placeholder to simplify valid usage requirements.
Memory Aliasing
A range of a VkDeviceMemory
allocation is aliased if it is bound to
multiple resources simultaneously, as described below, via
vkBindImageMemory, vkBindBufferMemory,
vkBindAccelerationStructureMemoryNV,
via sparse memory bindings,
or by binding the memory to resources in multiple Vulkan instances or
external APIs using external memory handle export and import mechanisms.
Consider two resources, resourceA and resourceB, bound respectively to
memory rangeA and rangeB.
Let paddedRangeA and paddedRangeB be, respectively, rangeA and
rangeB aligned to bufferImageGranularity
.
If the resources are both linear or both non-linear (as defined in the
Glossary), then the resources alias the
memory in the intersection of rangeA and rangeB.
If one resource is linear and the other is non-linear, then the resources
alias the memory in the intersection of paddedRangeA and paddedRangeB.
Applications can alias memory, but use of multiple aliases is subject to several constraints.
Memory aliasing can be useful to reduce the total device memory footprint of an application, if some large resources are used for disjoint periods of time.
When a non-linear,
non-VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
image is bound to an aliased
range, all image subresources of the image overlap the range.
When a linear image is bound to an aliased range, the image subresources
that (according to the image’s advertised layout) include bytes from the
aliased range overlap the range.
When a VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT
image has sparse image
blocks bound to an aliased range, only image subresources including those
sparse image blocks overlap the range, and when the memory bound to the
image’s mip tail overlaps an aliased range all image subresources in the mip
tail overlap the range.
Buffers, and linear image subresources in either the
VK_IMAGE_LAYOUT_PREINITIALIZED
or VK_IMAGE_LAYOUT_GENERAL
layouts, are host-accessible subresources.
That is, the host has a well-defined addressing scheme to interpret the
contents, and thus the layout of the data in memory can be consistently
interpreted across aliases if each of those aliases is a host-accessible
subresource.
Non-linear images, and linear image subresources in other layouts, are not
host-accessible.
If two aliases are both host-accessible, then they interpret the contents of the memory in consistent ways, and data written to one alias can be read by the other alias.
If two aliases are both images that were created with identical creation
parameters, both were created with the VK_IMAGE_CREATE_ALIAS_BIT
flag
set, and both are bound identically to memory
except for VkBindImageMemoryDeviceGroupInfo::pDeviceIndices
and
VkBindImageMemoryDeviceGroupInfo::pSplitInstanceBindRegions
,
then they interpret the contents of the memory in consistent ways, and data
written to one alias can be read by the other alias.
Additionally, if an individual plane of a multi-planar image and a single-plane image alias the same memory, then they also interpret the contents of the memory in consistent ways under the same conditions, but with the following modifications:
- Both must have been created with the
VK_IMAGE_CREATE_DISJOINT_BIT
flag. - The single-plane image must have a VkFormat that is equivalent to that of the multi-planar image’s individual plane.
- The single-plane image and the individual plane of the multi-planar
image must be bound identically to memory
except for VkBindImageMemoryDeviceGroupInfo::
pDeviceIndices
and VkBindImageMemoryDeviceGroupInfo::pSplitInstanceBindRegions
. - The
width
andheight
of the single-plane image are derived from the multi-planar image’s dimensions in the manner listed for plane compatibility for the aliased plane. - If either image’s
tiling
isVK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT
, then both images must be linear. - All other creation parameters must be identical
Aliases created by binding the same memory to resources in multiple Vulkan instances or external APIs using external memory handle export and import mechanisms interpret the contents of the memory in consistent ways, and data written to one alias can be read by the other alias.
Otherwise, the aliases interpret the contents of the memory differently, and writes via one alias make the contents of memory partially or completely undefined: to the other alias. If the first alias is a host-accessible subresource, then the bytes affected are those written by the memory operations according to its addressing scheme. If the first alias is not host-accessible, then the bytes affected are those overlapped by the image subresources that were written. If the second alias is a host-accessible subresource, the affected bytes become undefined:. If the second alias is not host-accessible, all sparse image blocks (for sparse partially-resident images) or all image subresources (for non-sparse image and fully resident sparse images) that overlap the affected bytes become undefined:.
If any image subresources are made undefined: due to writes to an alias,
then each of those image subresources must have its layout transitioned
from VK_IMAGE_LAYOUT_UNDEFINED
to a valid layout before it is used, or
from VK_IMAGE_LAYOUT_PREINITIALIZED
if the memory has been written by
the host.
If any sparse blocks of a sparse image have been made undefined:, then only
the image subresources containing them must be transitioned.
Use of an overlapping range by two aliases must be separated by a memory dependency using the appropriate access types if at least one of those uses performs writes, whether the aliases interpret memory consistently or not. If buffer or image memory barriers are used, the scope of the barrier must contain the entire range and/or set of image subresources that overlap.
If two aliasing image views are used in the same framebuffer, then the
render pass must declare the attachments using the
VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT
, and
follow the other rules listed in that section.
Memory recycled via an application suballocator (i.e. without freeing and reallocating the memory objects) is not substantially different from memory aliasing. However, a suballocator usually waits on a fence before recycling a region of memory, and signaling a fence involves sufficient implicit dependencies to satisfy all the above requirements.
Resource Memory Overlap
Applications can safely access a resource concurrently as long as the memory locations do not overlap as defined in Memory Location. This includes aliased resources if such aliasing is well-defined. It also includes access from different queues and/or queue families if such concurrent access is supported by the resource. Transfer commands only access memory locations specified by the range of the transfer command.
The intent is that buffers (or linear images) can be accessed concurrently, even when they share cache lines, but otherwise do not access the same memory range. The concept of a device cache line size is not exposed in the memory model.
Buffer Collections
Definitions
- FIDL - Fuchsia Interface Definition Language.
The declarative language used to define FIDL interprocess communication
interfaces on Fuchsia.
FIDL files use the
fidl
extension. FIDL is also used to refer to the services defined by interfaces declared in the FIDL language - Sysmem - The FIDL service that facilitates optimal buffer sharing and reuse on Fuchsia
- client - Any participant of the buffer collection e.g. the Vulkan application
- token - A
zx_handle_t
Zircon channel object that allows participation in the buffer collection
Platform Initialization for Buffer Collections
To initialize a buffer collection on Fuchsia:
- Connect to the Sysmem service to initialize a Sysmem allocator
- Create an initial buffer collection token using the Sysmem allocator
- Duplicate the token for each participant beyond the initiator
- See the Sysmem Overview and fuchsia.sysmem FIDL documentation on fuchsia.dev for more detailed information
Create the Buffer Collection
Set the Constraints
Buffer collections can be established for VkImage allocations or VkBuffer allocations.
Set Image-Based Buffer Collection Constraints
Set Buffer-Based Buffer Collection Constraints
Retrieve Buffer Collection Properties
Memory Allocation
To import memory from a buffer collection into a VkImage or a
VkBuffer, chain a VkImportMemoryBufferCollectionFUCHSIA
structure to the pNext
member of the VkMemoryAllocateInfo in the
call to vkAllocateMemory.