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

VkBufferOpaque handle to a buffer object
vkCreateBufferCreate a new buffer object
VkBufferCreateInfoStructure specifying the parameters of a newly created buffer object
VkBufferUsageFlags2CreateInfoKHRExtended buffer usage flags
VkBufferUsageFlagBits2KHRBitmask controlling how a pipeline is created
VkBufferUsageFlags2KHRBitmask of VkBufferUsageFlagBits2KHR
VkBufferUsageFlagBitsBitmask specifying allowed usage of a buffer
VkBufferUsageFlagsBitmask of VkBufferUsageFlagBits
VkBufferCreateFlagBitsBitmask specifying additional parameters of a buffer
VkBufferCreateFlagsBitmask of VkBufferCreateFlagBits
VkDedicatedAllocationBufferCreateInfoNVSpecify that a buffer is bound to a dedicated memory resource
VkExternalMemoryBufferCreateInfoSpecify that a buffer may be backed by external memory
VkBufferOpaqueCaptureAddressCreateInfoRequest a specific address for a buffer
VkBufferDeviceAddressCreateInfoEXTRequest a specific address for a buffer
VkBufferCollectionBufferCreateInfoFUCHSIACreate a VkBufferCollectionFUCHSIA-compatible VkBuffer
vkDestroyBufferDestroy a buffer object

Buffer Views

VkBufferViewOpaque handle to a buffer view object
vkCreateBufferViewCreate a new buffer view object
VkBufferViewCreateInfoStructure specifying parameters of a newly created buffer view
VkBufferViewCreateFlagsReserved for future use
vkDestroyBufferViewDestroy a buffer view object

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.

Images

VkImageOpaque handle to an image object
vkCreateImageCreate a new image object
VkImageCreateInfoStructure specifying the parameters of a newly created image object
VkBufferCollectionImageCreateInfoFUCHSIACreate a VkBufferCollectionFUCHSIA-compatible VkImage
VkImageStencilUsageCreateInfoSpecify separate usage flags for the stencil aspect of a depth-stencil image
VkDedicatedAllocationImageCreateInfoNVSpecify that an image is bound to a dedicated memory resource
VkExternalMemoryImageCreateInfoSpecify that an image may be backed by external memory
VkExternalMemoryImageCreateInfoNVSpecify that an image may be backed by external memory
VkExternalFormatANDROIDStructure containing an Android hardware buffer external format
VkExternalFormatQNXStructure containing a QNX Screen buffer external format
VkImageSwapchainCreateInfoKHRSpecify that an image will be bound to swapchain memory
VkImageFormatListCreateInfoSpecify that an image can be used with a particular set of formats
VkImageDrmFormatModifierListCreateInfoEXTSpecify that an image must be created with a DRM format modifier from the provided list
VkImageDrmFormatModifierExplicitCreateInfoEXTSpecify that an image be created with the provided DRM format modifier and explicit memory layout
VkImageCompressionControlEXTSpecify image compression properties
VkImageCompressionFlagBitsEXTBitmask specifying image compression controls
VkImageCompressionFlagsEXTBitmask of VkImageCompressionFlagBitsEXT
VkImageCompressionFixedRateFlagsEXTBitmask of VkImageCompressionFixedRateFlagBitsEXT
VkImageCompressionFixedRateFlagBitsEXTBitmask specifying fixed rate image compression rates
VkImageCompressionPropertiesEXTCompression properties of an image
VkImageAlignmentControlCreateInfoMESASpecify image alignment
VkImageUsageFlagBitsBitmask specifying intended usage of an image
VkImageUsageFlagsBitmask of VkImageUsageFlagBits
VkImageCreateFlagBitsBitmask specifying additional parameters of an image
VkImageCreateFlagsBitmask of VkImageCreateFlagBits
VkImageTypeSpecifies the type of an image object
VkImageTilingSpecifies the tiling arrangement of data in an image
vkGetImageSubresourceLayoutRetrieve information about an image subresource
VkImageSubresourceStructure specifying an image subresource
VkSubresourceLayoutStructure specifying subresource layout
vkGetImageSubresourceLayout2KHRRetrieve information about an image subresource
VkImageSubresource2KHRStructure specifying an image subresource
VkSubresourceLayout2KHRStructure specifying subresource layout
VkSubresourceHostMemcpySizeEXTMemory size needed to copy to or from an image on the host with VK_HOST_IMAGE_COPY_MEMCPY_EXT
vkGetDeviceImageSubresourceLayoutKHRRetrieve information about an image subresource without an image object
VkDeviceImageSubresourceInfoKHRImage creation information for querying subresource layout
vkGetImageDrmFormatModifierPropertiesEXTReturns an image’s DRM format modifier
VkImageDrmFormatModifierPropertiesEXTProperties of an image’s Linux DRM format modifier
vkDestroyImageDestroy an image object

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.

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:

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:

  • widthn+1 = max(⌊widthn/2⌋, 1)
  • heightn+1 = max(⌊heightn/2⌋, 1)
  • depthn+1 = max(⌊depthn/2⌋, 1)

where widthn, heightn, and depthn 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(width0, height0, depth0))⌋ + 1

where width0, height0, and depth0 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:

  • widthn+1 = max(⌈widthn/2⌉, 2)
  • heightn+1 = max(⌈heightn/2⌉, 2)
  • depthn+1 = max(⌈depthn/2⌉, 2)

where widthn, heightn, and depthn 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(width0, height0, depth0))⌉

where width0, height0, and depth0 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.

VkImageLayoutLayout of image and image subresources

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 and VK_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 and VK_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

VkImageViewOpaque handle to an image view object
VK_REMAINING_ARRAY_LAYERSSentinel for all remaining array layers
VK_REMAINING_MIP_LEVELSSentinel for all remaining mipmap levels
VkImageViewTypeImage view types
vkCreateImageViewCreate an image view from an existing image
VkImageViewCreateInfoStructure specifying parameters of a newly created image view
VkImageViewCreateFlagBitsBitmask specifying additional parameters of an image view
VkImageViewCreateFlagsReserved for future use
VkImageViewUsageCreateInfoSpecify the intended usage of an image view
VkImageViewSlicedCreateInfoEXTSpecify the subset of 3D slices of an image view
VK_REMAINING_3D_SLICES_EXTSentinel for all remaining 3D slices
VkImageSubresourceRangeStructure specifying an image subresource range
VkImageAspectFlagBitsBitmask specifying which aspects of an image are included in a view
VkImageAspectFlagsBitmask of VkImageAspectFlagBits
VkComponentMappingStructure specifying a color component mapping
VkComponentSwizzleSpecify how a component is swizzled
VkImageViewASTCDecodeModeEXTStructure describing the ASTC decode mode for an image view
VkImageViewSampleWeightCreateInfoQCOMStructure describing weight sampling parameters for image view
vkDestroyImageViewDestroy an image view object
vkGetImageViewHandleNVXGet the handle for an image view for a specific descriptor type
VkImageViewHandleInfoNVXStructure specifying the image view for handle queries
vkGetImageViewAddressNVXGet the device address of an image view
VkImageViewAddressPropertiesNVXStructure specifying the image view for handle queries

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.

VkImageViewMinLodCreateInfoEXTStructure describing the minimum LOD of an image view

Acceleration Structures

VkAccelerationStructureKHROpaque handle to an acceleration structure object
VkAccelerationStructureNVOpaque handle to an acceleration structure object
vkCreateAccelerationStructureNVCreate a new acceleration structure object
VkAccelerationStructureCreateInfoNVStructure specifying the parameters of a newly created acceleration structure object
VkAccelerationStructureInfoNVStructure specifying the parameters of acceleration structure object
vkCreateAccelerationStructureKHRCreate a new acceleration structure object
VkAccelerationStructureCreateInfoKHRStructure specifying the parameters of a newly created acceleration structure object
VkAccelerationStructureMotionInfoNVStructure specifying the parameters of a newly created acceleration structure object
VkAccelerationStructureMotionInfoFlagsNVReserved for future use
vkGetAccelerationStructureBuildSizesKHRRetrieve the required size for an acceleration structure
VkAccelerationStructureBuildSizesInfoKHRStructure specifying build sizes for an acceleration structure
VkAccelerationStructureTypeKHRType of acceleration structure
VkAccelerationStructureCreateFlagBitsKHRBitmask specifying additional creation parameters for acceleration structure
VkAccelerationStructureCreateFlagsKHRBitmask of VkAccelerationStructureCreateFlagBitsKHR
VkBuildAccelerationStructureFlagBitsKHRBitmask specifying additional parameters for acceleration structure builds
VkBuildAccelerationStructureFlagsKHRBitmask of VkBuildAccelerationStructureFlagBitsKHR
VkGeometryNVStructure specifying a geometry in a bottom-level acceleration structure
VkGeometryTypeKHREnum specifying which type of geometry is provided
VkGeometryFlagBitsKHRBitmask specifying additional parameters for a geometry
VkGeometryFlagsKHRBitmask of VkGeometryFlagBitsKHR
VkGeometryDataNVStructure specifying geometry in a bottom-level acceleration structure
VkGeometryTrianglesNVStructure specifying a triangle geometry in a bottom-level acceleration structure
VkGeometryAABBNVStructure specifying axis-aligned bounding box geometry in a bottom-level acceleration structure
vkDestroyAccelerationStructureKHRDestroy an acceleration structure object
vkDestroyAccelerationStructureNVDestroy an acceleration structure object
vkGetAccelerationStructureMemoryRequirementsNVGet acceleration structure memory requirements
VkAccelerationStructureMemoryRequirementsInfoNVStructure specifying acceleration to query for memory requirements
VkAccelerationStructureMemoryRequirementsTypeNVAcceleration structure memory requirement type
VkAccelerationStructureBuildTypeKHRAcceleration structure build type
vkBindAccelerationStructureMemoryNVBind acceleration structure memory
VkBindAccelerationStructureMemoryInfoNVStructure specifying acceleration structure memory binding
vkGetAccelerationStructureHandleNVGet opaque acceleration structure handle
vkGetAccelerationStructureDeviceAddressKHRQuery an address of an acceleration structure
VkAccelerationStructureDeviceAddressInfoKHRStructure specifying the acceleration structure to query an address for

Micromaps

VkMicromapEXTOpaque handle to a micromap object
vkCreateMicromapEXTCreate a new micromap object
VkMicromapCreateInfoEXTStructure specifying the parameters of a newly created micromap object
vkGetMicromapBuildSizesEXTRetrieve the required size for a micromap
VkMicromapBuildSizesInfoEXTStructure specifying build sizes for a micromap
VkMicromapTypeEXTType of micromap
VkMicromapCreateFlagBitsEXTBitmask specifying additional creation parameters for micromap
VkMicromapCreateFlagsEXTBitmask of VkMicromapCreateFlagBitsEXT
VkBuildMicromapFlagBitsEXTBitmask specifying additional parameters for micromap builds
VkBuildMicromapFlagsEXTBitmask of VkBuildMicromapFlagBitsEXT
vkDestroyMicromapEXTDestroy a micromap object

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.

vkGetBufferMemoryRequirementsReturns the memory requirements for specified Vulkan object
vkGetImageMemoryRequirementsReturns the memory requirements for specified Vulkan object
VkMemoryRequirementsStructure specifying memory requirements

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 a VkBuffer not created with the VK_BUFFER_CREATE_SPARSE_BINDING_BIT or VK_BUFFER_CREATE_PROTECTED_BIT bits set, or if image is a linear image that was not created with the VK_IMAGE_CREATE_PROTECTED_BIT bit set, 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.
  • If buffer was created with VkExternalMemoryBufferCreateInfo::handleTypes set to 0 or image was created with VkExternalMemoryImageCreateInfo::handleTypes set to 0, the 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.
  • The memoryTypeBits member is identical for all VkBuffer objects created with the same value for the flags and usage members in the VkBufferCreateInfo structure and the handleTypes member of the VkExternalMemoryBufferCreateInfo 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 and VkExternalMemoryBufferCreateInfo::handleTypes, 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.
  • The alignment member is a power of two.
  • The 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.
  • If the maintenance4 feature is enabled, then the alignment member is identical for all VkImage objects created with the same combination of values for the flags, imageType, format, extent, mipLevels, arrayLayers, samples, tiling and usage members in the VkImageCreateInfo structure passed to vkCreateImage.
  • The alignment member satisfies the buffer descriptor offset alignment requirements associated with the VkBuffer’s usage:
    • If usage included VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, alignmentmust be an integer multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment.
    • If usage included VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, alignment must be an integer multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment.
    • If usage included VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, alignment must be an integer multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment.
  • For images created with a color format, the 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, the VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT bit of the flags member, the VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT bit of the usage member if the VkPhysicalDeviceHostImageCopyPropertiesEXT::identicalMemoryTypeRequirements property is VK_FALSE, handleTypes member of VkExternalMemoryImageCreateInfo, and the VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT of the usage member in the VkImageCreateInfo structure passed to vkCreateImage.
  • For images created with a depth/stencil format, the 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, the VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT bit of the flags member, the VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT bit of the usage member if the VkPhysicalDeviceHostImageCopyPropertiesEXT::identicalMemoryTypeRequirements property is VK_FALSE, handleTypes member of VkExternalMemoryImageCreateInfo, and the VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT of the usage member in the VkImageCreateInfo structure passed to vkCreateImage.
  • If the memory requirements are for a 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 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.

    The implication of this requirement is that lazily allocated memory is disallowed for buffers in all cases.

  • The size member is identical for all VkBuffer objects created with the same combination of creation parameters specified in VkBufferCreateInfo and its pNext chain.
  • The size member is identical for all VkImage objects created with the same combination of creation parameters specified in VkImageCreateInfo and its pNext 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:
vkGetBufferMemoryRequirements2Returns the memory requirements for specified Vulkan object
vkGetDeviceBufferMemoryRequirementsReturns the memory requirements for specified Vulkan object
VkBufferMemoryRequirementsInfo2(None)
VkDeviceBufferMemoryRequirements(None)
vkGetImageMemoryRequirements2Returns the memory requirements for specified Vulkan object
vkGetDeviceImageMemoryRequirementsReturns the memory requirements for specified Vulkan object
VkImageMemoryRequirementsInfo2(None)
VkDeviceImageMemoryRequirements(None)
VkImagePlaneMemoryRequirementsInfoStructure specifying image plane for memory requirements
VkMemoryRequirements2Structure specifying memory requirements
VkMemoryDedicatedRequirementsStructure describing dedicated allocation requirements of buffer and image resources
vkBindBufferMemoryBind device memory to a buffer object
vkBindBufferMemory2Bind device memory to buffer objects
VkBindBufferMemoryInfoStructure specifying how to bind a buffer to memory
VkBindBufferMemoryDeviceGroupInfoStructure specifying device within a group to bind to
VkBindMemoryStatusKHRStructure specifying where to return memory binding status
vkBindImageMemoryBind device memory to an image object
vkBindImageMemory2Bind device memory to image objects
VkBindImageMemoryInfoStructure specifying how to bind an image to memory
VkBindImageMemoryDeviceGroupInfoStructure specifying device within a group to bind to
VkBindImageMemorySwapchainInfoKHRStructure specifying swapchain image memory to bind to
VkBindImagePlaneMemoryInfoStructure specifying how to bind an image plane to memory

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

VkSharingModeBuffer and image sharing modes

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

  1. Release exclusive ownership from the source instance or API.
  2. Ensure the release operation has completed using semaphores or fences.
  3. 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 and height 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 is VK_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

VkBufferCollectionFUCHSIAOpaque handle to a buffer collection object

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

vkCreateBufferCollectionFUCHSIACreate a new buffer collection
VkBufferCollectionCreateInfoFUCHSIAStructure specifying desired parameters to create the buffer collection

Set the Constraints

Buffer collections can be established for VkImage allocations or VkBuffer allocations.

Set Image-Based Buffer Collection Constraints

vkSetBufferCollectionImageConstraintsFUCHSIASet image-based constraints for a buffer collection
VkImageConstraintsInfoFUCHSIAStructure of image-based buffer collection constraints
VkImageConstraintsInfoFlagsFUCHSIAReserved for future use
VkImageConstraintsInfoFlagBitsFUCHSIABitmask specifying image constraints flags
VkImageFormatConstraintsInfoFUCHSIAStructure image-based buffer collection constraints
VkImageFormatConstraintsFlagsFUCHSIAReserved for future use
VkBufferCollectionConstraintsInfoFUCHSIAStructure of general buffer collection constraints
VkSysmemColorSpaceFUCHSIAStructure describing the buffer collections color space

Set Buffer-Based Buffer Collection Constraints

vkSetBufferCollectionBufferConstraintsFUCHSIASet buffer-based constraints for a buffer collection
VkBufferConstraintsInfoFUCHSIAStructure buffer-based buffer collection constraints

Retrieve Buffer Collection Properties

vkGetBufferCollectionPropertiesFUCHSIARetrieve properties from a buffer collection
VkBufferCollectionPropertiesFUCHSIAStructure specifying the negotiated format chosen by Sysmem

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.

VkImportMemoryBufferCollectionFUCHSIAStructure to specify the Sysmem buffer to import
vkDestroyBufferCollectionFUCHSIADestroy a buffer collection