11. Memory Allocation
Vulkan memory is broken up into two categories, host memory and device memory.
11.1. Host Memory
Host memory is memory needed by the Vulkan implementation for non-device-visible storage.
Note
This memory may be used to store the implementation’s representation and state of Vulkan objects. |
Vulkan provides applications the opportunity to perform host memory allocations on behalf of the Vulkan implementation. If this feature is not used, the implementation will perform its own memory allocations. Since most memory allocations are off the critical path, this is not meant as a performance feature. Rather, this can be useful for certain embedded systems, for debugging purposes (e.g. putting a guard page after all host allocations), or for memory allocation logging.
Allocators are provided by the application as a pointer to a
VkAllocationCallbacks
structure:
// Provided by VK_VERSION_1_0
typedef struct VkAllocationCallbacks {
void* pUserData;
PFN_vkAllocationFunction pfnAllocation;
PFN_vkReallocationFunction pfnReallocation;
PFN_vkFreeFunction pfnFree;
PFN_vkInternalAllocationNotification pfnInternalAllocation;
PFN_vkInternalFreeNotification pfnInternalFree;
} VkAllocationCallbacks;
-
pUserData
is a value to be interpreted by the implementation of the callbacks. When any of the callbacks inVkAllocationCallbacks
are called, the Vulkan implementation will pass this value as the first parameter to the callback. This value can vary each time an allocator is passed into a command, even when the same object takes an allocator in multiple commands. -
pfnAllocation
is a PFN_vkAllocationFunction pointer to an application-defined memory allocation function. -
pfnReallocation
is a PFN_vkReallocationFunction pointer to an application-defined memory reallocation function. -
pfnFree
is a PFN_vkFreeFunction pointer to an application-defined memory free function. -
pfnInternalAllocation
is a PFN_vkInternalAllocationNotification pointer to an application-defined function that is called by the implementation when the implementation makes internal allocations. -
pfnInternalFree
is a PFN_vkInternalFreeNotification pointer to an application-defined function that is called by the implementation when the implementation frees internal allocations.
The type of pfnAllocation
is:
// Provided by VK_VERSION_1_0
typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)(
void* pUserData,
size_t size,
size_t alignment,
VkSystemAllocationScope allocationScope);
-
pUserData
is the value specified for VkAllocationCallbacks::pUserData
in the allocator specified by the application. -
size
is the size in bytes of the requested allocation. -
alignment
is the requested alignment of the allocation in bytes and must be a power of two. -
allocationScope
is a VkSystemAllocationScope value specifying the allocation scope of the lifetime of the allocation, as described here.
If pfnAllocation
is unable to allocate the requested memory, it must
return NULL
.
If the allocation was successful, it must return a valid pointer to memory
allocation containing at least size
bytes, and with the pointer value
being a multiple of alignment
.
Note
Correct Vulkan operation cannot be assumed if the application does not follow these rules. For example, |
If pfnAllocation
returns NULL
, and if the implementation is unable
to continue correct processing of the current command without the requested
allocation, it must treat this as a runtime error, and generate
VK_ERROR_OUT_OF_HOST_MEMORY
at the appropriate time for the command in
which the condition was detected, as described in Return Codes.
If the implementation is able to continue correct processing of the current
command without the requested allocation, then it may do so, and must not
generate VK_ERROR_OUT_OF_HOST_MEMORY
as a result of this failed
allocation.
The type of pfnReallocation
is:
// Provided by VK_VERSION_1_0
typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)(
void* pUserData,
void* pOriginal,
size_t size,
size_t alignment,
VkSystemAllocationScope allocationScope);
-
pUserData
is the value specified for VkAllocationCallbacks::pUserData
in the allocator specified by the application. -
pOriginal
must be eitherNULL
or a pointer previously returned bypfnReallocation
orpfnAllocation
of a compatible allocator. -
size
is the size in bytes of the requested allocation. -
alignment
is the requested alignment of the allocation in bytes and must be a power of two. -
allocationScope
is a VkSystemAllocationScope value specifying the allocation scope of the lifetime of the allocation, as described here.
If the reallocation was successful, pfnReallocation
must return an
allocation with enough space for size
bytes, and the contents of the
original allocation from bytes zero to min(original size, new size) -
1 must be preserved in the returned allocation.
If size
is larger than the old size, the contents of the additional
space are undefined.
If satisfying these requirements involves creating a new allocation, then
the old allocation should be freed.
If pOriginal
is NULL
, then pfnReallocation
must behave
equivalently to a call to PFN_vkAllocationFunction with the same
parameter values (without pOriginal
).
If size
is zero, then pfnReallocation
must behave equivalently
to a call to PFN_vkFreeFunction with the same pUserData
parameter value, and pMemory
equal to pOriginal
.
If pOriginal
is non-NULL
, the implementation must ensure that
alignment
is equal to the alignment
used to originally allocate
pOriginal
.
If this function fails and pOriginal
is non-NULL
the application
must not free the old allocation.
pfnReallocation
must follow the same
rules for return values as
PFN_vkAllocationFunction
.
The type of pfnFree
is:
// Provided by VK_VERSION_1_0
typedef void (VKAPI_PTR *PFN_vkFreeFunction)(
void* pUserData,
void* pMemory);
-
pUserData
is the value specified for VkAllocationCallbacks::pUserData
in the allocator specified by the application. -
pMemory
is the allocation to be freed.
pMemory
may be NULL
, which the callback must handle safely.
If pMemory
is non-NULL
, it must be a pointer previously allocated
by pfnAllocation
or pfnReallocation
.
The application should free this memory.
The type of pfnInternalAllocation
is:
// Provided by VK_VERSION_1_0
typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)(
void* pUserData,
size_t size,
VkInternalAllocationType allocationType,
VkSystemAllocationScope allocationScope);
-
pUserData
is the value specified for VkAllocationCallbacks::pUserData
in the allocator specified by the application. -
size
is the requested size of an allocation. -
allocationType
is a VkInternalAllocationType value specifying the requested type of an allocation. -
allocationScope
is a VkSystemAllocationScope value specifying the allocation scope of the lifetime of the allocation, as described here.
This is a purely informational callback.
The type of pfnInternalFree
is:
// Provided by VK_VERSION_1_0
typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)(
void* pUserData,
size_t size,
VkInternalAllocationType allocationType,
VkSystemAllocationScope allocationScope);
-
pUserData
is the value specified for VkAllocationCallbacks::pUserData
in the allocator specified by the application. -
size
is the requested size of an allocation. -
allocationType
is a VkInternalAllocationType value specifying the requested type of an allocation. -
allocationScope
is a VkSystemAllocationScope value specifying the allocation scope of the lifetime of the allocation, as described here.
Each allocation has an allocation scope defining its lifetime and which
object it is associated with.
Possible values passed to the allocationScope
parameter of the
callback functions specified by VkAllocationCallbacks, indicating the
allocation scope, are:
// Provided by VK_VERSION_1_0
typedef enum VkSystemAllocationScope {
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1,
VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2,
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3,
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4,
} VkSystemAllocationScope;
-
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND
specifies that the allocation is scoped to the duration of the Vulkan command. -
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
specifies that the allocation is scoped to the lifetime of the Vulkan object that is being created or used. -
VK_SYSTEM_ALLOCATION_SCOPE_CACHE
specifies that the allocation is scoped to the lifetime of aVkPipelineCache
orVkValidationCacheEXT
object. -
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE
specifies that the allocation is scoped to the lifetime of the Vulkan device. -
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
specifies that the allocation is scoped to the lifetime of the Vulkan instance.
Most Vulkan commands operate on a single object, or there is a sole object
that is being created or manipulated.
When an allocation uses an allocation scope of
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
or
VK_SYSTEM_ALLOCATION_SCOPE_CACHE
, the allocation is scoped to the
object being created or manipulated.
When an implementation requires host memory, it will make callbacks to the application using the most specific allocator and allocation scope available:
-
If an allocation is scoped to the duration of a command, the allocator will use the
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND
allocation scope. The most specific allocator available is used: if the object being created or manipulated has an allocator, that object’s allocator will be used, else if the parentVkDevice
has an allocator it will be used, else if the parentVkInstance
has an allocator it will be used. Else, -
If an allocation is associated with a
VkValidationCacheEXT
orVkPipelineCache
object, the allocator will use theVK_SYSTEM_ALLOCATION_SCOPE_CACHE
allocation scope. The most specific allocator available is used (cache, else device, else instance). Else, -
If an allocation is scoped to the lifetime of an object, that object is being created or manipulated by the command, and that object’s type is not
VkDevice
orVkInstance
, the allocator will use an allocation scope ofVK_SYSTEM_ALLOCATION_SCOPE_OBJECT
. The most specific allocator available is used (object, else device, else instance). Else, -
If an allocation is scoped to the lifetime of a device, the allocator will use an allocation scope of
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE
. The most specific allocator available is used (device, else instance). Else, -
If the allocation is scoped to the lifetime of an instance and the instance has an allocator, its allocator will be used with an allocation scope of
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE
. -
Otherwise an implementation will allocate memory through an alternative mechanism that is unspecified.
Objects that are allocated from pools do not specify their own allocator. When an implementation requires host memory for such an object, that memory is sourced from the object’s parent pool’s allocator.
The application is not expected to handle allocating memory that is intended
for execution by the host due to the complexities of differing security
implementations across multiple platforms.
The implementation will allocate such memory internally and invoke an
application provided informational callback when these internal
allocations are allocated and freed.
Upon allocation of executable memory, pfnInternalAllocation
will be
called.
Upon freeing executable memory, pfnInternalFree
will be called.
An implementation will only call an informational callback for executable
memory allocations and frees.
The allocationType
parameter to the pfnInternalAllocation
and
pfnInternalFree
functions may be one of the following values:
// Provided by VK_VERSION_1_0
typedef enum VkInternalAllocationType {
VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0,
} VkInternalAllocationType;
-
VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE
specifies that the allocation is intended for execution by the host.
An implementation must only make calls into an application-provided allocator during the execution of an API command. An implementation must only make calls into an application-provided allocator from the same thread that called the provoking API command. The implementation should not synchronize calls to any of the callbacks. If synchronization is needed, the callbacks must provide it themselves. The informational callbacks are subject to the same restrictions as the allocation callbacks.
If an implementation intends to make calls through a
VkAllocationCallbacks
structure between the time a vkCreate*
command returns and the time a corresponding vkDestroy*
command
begins, that implementation must save a copy of the allocator before the
vkCreate*
command returns.
The callback functions and any data structures they rely upon must remain
valid for the lifetime of the object they are associated with.
If an allocator is provided to a vkCreate*
command, a compatible
allocator must be provided to the corresponding vkDestroy*
command.
Two VkAllocationCallbacks
structures are compatible if memory
allocated with pfnAllocation
or pfnReallocation
in each can be
freed with pfnReallocation
or pfnFree
in the other.
An allocator must not be provided to a vkDestroy*
command if an
allocator was not provided to the corresponding vkCreate*
command.
If a non-NULL
allocator is used, the pfnAllocation
,
pfnReallocation
and pfnFree
members must be non-NULL
and
point to valid implementations of the callbacks.
An application can choose to not provide informational callbacks by setting
both pfnInternalAllocation
and pfnInternalFree
to NULL
.
pfnInternalAllocation
and pfnInternalFree
must either both be
NULL
or both be non-NULL
.
If pfnAllocation
or pfnReallocation
fail, the implementation
may fail object creation and/or generate a
VK_ERROR_OUT_OF_HOST_MEMORY
error, as appropriate.
Allocation callbacks must not call any Vulkan commands.
The following sets of rules define when an implementation is permitted to call the allocator callbacks.
pfnAllocation
or pfnReallocation
may be called in the following
situations:
-
Allocations scoped to a
VkDevice
orVkInstance
may be allocated from any API command. -
Allocations scoped to a command may be allocated from any API command.
-
Allocations scoped to a
VkPipelineCache
may only be allocated from:-
vkCreatePipelineCache
-
vkMergePipelineCaches
fordstCache
-
vkCreateGraphicsPipelines
forpipelineCache
-
vkCreateComputePipelines
forpipelineCache
-
-
Allocations scoped to a
VkValidationCacheEXT
may only be allocated from:-
vkCreateValidationCacheEXT
-
vkMergeValidationCachesEXT
fordstCache
-
vkCreateShaderModule
forvalidationCache
in VkShaderModuleValidationCacheCreateInfoEXT
-
-
Allocations scoped to a
VkDescriptorPool
may only be allocated from:-
any command that takes the pool as a direct argument
-
vkAllocateDescriptorSets
for thedescriptorPool
member of itspAllocateInfo
parameter -
vkCreateDescriptorPool
-
-
Allocations scoped to a
VkCommandPool
may only be allocated from:-
any command that takes the pool as a direct argument
-
vkCreateCommandPool
-
vkAllocateCommandBuffers
for thecommandPool
member of itspAllocateInfo
parameter -
any
vkCmd*
command whosecommandBuffer
was allocated from thatVkCommandPool
-
-
Allocations scoped to any other object may only be allocated in that object’s
vkCreate*
command.
pfnFree
, or pfnReallocation
with zero size
, may be called
in the following situations:
-
Allocations scoped to a
VkDevice
orVkInstance
may be freed from any API command. -
Allocations scoped to a command must be freed by any API command which allocates such memory.
-
Allocations scoped to a
VkPipelineCache
may be freed fromvkDestroyPipelineCache
. -
Allocations scoped to a
VkValidationCacheEXT
may be freed fromvkDestroyValidationCacheEXT
. -
Allocations scoped to a
VkDescriptorPool
may be freed from-
any command that takes the pool as a direct argument
-
-
Allocations scoped to a
VkCommandPool
may be freed from:-
any command that takes the pool as a direct argument
-
vkResetCommandBuffer
whosecommandBuffer
was allocated from thatVkCommandPool
-
-
Allocations scoped to any other object may be freed in that object’s
vkDestroy*
command. -
Any command that allocates host memory may also free host memory of the same scope.
11.2. Device Memory
Device memory is memory that is visible to the device — for example the contents of the image or buffer objects, which can be natively used by the device.
11.2.1. Device Memory Properties
Memory properties of a physical device describe the memory heaps and memory types available.
To query memory properties, call:
// Provided by VK_VERSION_1_0
void vkGetPhysicalDeviceMemoryProperties(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties* pMemoryProperties);
-
physicalDevice
is the handle to the device to query. -
pMemoryProperties
is a pointer to a VkPhysicalDeviceMemoryProperties structure in which the properties are returned.
The VkPhysicalDeviceMemoryProperties
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkPhysicalDeviceMemoryProperties {
uint32_t memoryTypeCount;
VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES];
uint32_t memoryHeapCount;
VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS];
} VkPhysicalDeviceMemoryProperties;
-
memoryTypeCount
is the number of valid elements in thememoryTypes
array. -
memoryTypes
is an array ofVK_MAX_MEMORY_TYPES
VkMemoryType structures describing the memory types that can be used to access memory allocated from the heaps specified bymemoryHeaps
. -
memoryHeapCount
is the number of valid elements in thememoryHeaps
array. -
memoryHeaps
is an array ofVK_MAX_MEMORY_HEAPS
VkMemoryHeap structures describing the memory heaps from which memory can be allocated.
The VkPhysicalDeviceMemoryProperties
structure describes a number of
memory heaps as well as a number of memory types that can be used to
access memory allocated in those heaps.
Each heap describes a memory resource of a particular size, and each memory
type describes a set of memory properties (e.g. host cached vs. uncached)
that can be used with a given memory heap.
Allocations using a particular memory type will consume resources from the
heap indicated by that memory type’s heap index.
More than one memory type may share each heap, and the heaps and memory
types provide a mechanism to advertise an accurate size of the physical
memory resources while allowing the memory to be used with a variety of
different properties.
The number of memory heaps is given by memoryHeapCount
and is less
than or equal to VK_MAX_MEMORY_HEAPS
.
Each heap is described by an element of the memoryHeaps
array as a
VkMemoryHeap structure.
The number of memory types available across all memory heaps is given by
memoryTypeCount
and is less than or equal to
VK_MAX_MEMORY_TYPES
.
Each memory type is described by an element of the memoryTypes
array
as a VkMemoryType structure.
At least one heap must include VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
in
VkMemoryHeap::flags
.
If there are multiple heaps that all have similar performance
characteristics, they may all include
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
.
In a unified memory architecture (UMA) system there is often only a single
memory heap which is considered to be equally “local” to the host and to
the device, and such an implementation must advertise the heap as
device-local.
Each memory type returned by vkGetPhysicalDeviceMemoryProperties must
have its propertyFlags
set to one of the following values:
-
0
-
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
-
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
-
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
-
VK_MEMORY_PROPERTY_PROTECTED_BIT
-
VK_MEMORY_PROPERTY_PROTECTED_BIT
|VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
-
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
-
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
-
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
|
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD
-
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
|
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
|
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
|
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
|
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
|
VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV
There must be at least one memory type with both the
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
and
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
bits set in its
propertyFlags
.
There must be at least one memory type with the
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
bit set in its
propertyFlags
.
If the deviceCoherentMemory
feature
is enabled, there must be at least one memory type with the
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
bit set in its
propertyFlags
.
For each pair of elements X and Y returned in memoryTypes
, X
must be placed at a lower index position than Y if:
-
the set of bit flags returned in the
propertyFlags
member of X is a strict subset of the set of bit flags returned in thepropertyFlags
member of Y; or -
the
propertyFlags
members of X and Y are equal, and X belongs to a memory heap with greater performance (as determined in an implementation-specific manner) ; or -
the
propertyFlags
members of Y includesVK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
orVK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD
and X does not
Note
There is no ordering requirement between X and Y elements for the case
their There may be a performance penalty for using device coherent or uncached device memory types, and using these accidentally is undesirable. In order to avoid this, memory types with these properties always appear at the end of the list; but are subject to the same rules otherwise. |
This ordering requirement enables applications to use a simple search loop to select the desired memory type along the lines of:
// Find a memory in `memoryTypeBitsRequirement` that includes all of `requiredProperties`
int32_t findProperties(const VkPhysicalDeviceMemoryProperties* pMemoryProperties,
uint32_t memoryTypeBitsRequirement,
VkMemoryPropertyFlags requiredProperties) {
const uint32_t memoryCount = pMemoryProperties->memoryTypeCount;
for (uint32_t memoryIndex = 0; memoryIndex < memoryCount; ++memoryIndex) {
const uint32_t memoryTypeBits = (1 << memoryIndex);
const bool isRequiredMemoryType = memoryTypeBitsRequirement & memoryTypeBits;
const VkMemoryPropertyFlags properties =
pMemoryProperties->memoryTypes[memoryIndex].propertyFlags;
const bool hasRequiredProperties =
(properties & requiredProperties) == requiredProperties;
if (isRequiredMemoryType && hasRequiredProperties)
return static_cast<int32_t>(memoryIndex);
}
// failed to find memory type
return -1;
}
// Try to find an optimal memory type, or if it does not exist try fallback memory type
// `device` is the VkDevice
// `image` is the VkImage that requires memory to be bound
// `memoryProperties` properties as returned by vkGetPhysicalDeviceMemoryProperties
// `requiredProperties` are the property flags that must be present
// `optimalProperties` are the property flags that are preferred by the application
VkMemoryRequirements memoryRequirements;
vkGetImageMemoryRequirements(device, image, &memoryRequirements);
int32_t memoryType =
findProperties(&memoryProperties, memoryRequirements.memoryTypeBits, optimalProperties);
if (memoryType == -1) // not found; try fallback properties
memoryType =
findProperties(&memoryProperties, memoryRequirements.memoryTypeBits, requiredProperties);
VK_MAX_MEMORY_TYPES
is the length of an array of VkMemoryType
structures describing memory types, as returned in
VkPhysicalDeviceMemoryProperties::memoryTypes
.
#define VK_MAX_MEMORY_TYPES 32U
VK_MAX_MEMORY_HEAPS
is the length of an array of VkMemoryHeap
structures describing memory heaps, as returned in
VkPhysicalDeviceMemoryProperties::memoryHeaps
.
#define VK_MAX_MEMORY_HEAPS 16U
To query memory properties, call:
// Provided by VK_VERSION_1_1
void vkGetPhysicalDeviceMemoryProperties2(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
or the equivalent command
// Provided by VK_KHR_get_physical_device_properties2
void vkGetPhysicalDeviceMemoryProperties2KHR(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceMemoryProperties2* pMemoryProperties);
-
physicalDevice
is the handle to the device to query. -
pMemoryProperties
is a pointer to a VkPhysicalDeviceMemoryProperties2 structure in which the properties are returned.
vkGetPhysicalDeviceMemoryProperties2
behaves similarly to
vkGetPhysicalDeviceMemoryProperties, with the ability to return
extended information in a pNext
chain of output structures.
The VkPhysicalDeviceMemoryProperties2
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkPhysicalDeviceMemoryProperties2 {
VkStructureType sType;
void* pNext;
VkPhysicalDeviceMemoryProperties memoryProperties;
} VkPhysicalDeviceMemoryProperties2;
or the equivalent
// Provided by VK_KHR_get_physical_device_properties2
typedef VkPhysicalDeviceMemoryProperties2 VkPhysicalDeviceMemoryProperties2KHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memoryProperties
is a VkPhysicalDeviceMemoryProperties structure which is populated with the same values as in vkGetPhysicalDeviceMemoryProperties.
The VkMemoryHeap
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkMemoryHeap {
VkDeviceSize size;
VkMemoryHeapFlags flags;
} VkMemoryHeap;
-
size
is the total memory size in bytes in the heap. -
flags
is a bitmask of VkMemoryHeapFlagBits specifying attribute flags for the heap.
Bits which may be set in VkMemoryHeap::flags
, indicating
attribute flags for the heap, are:
// Provided by VK_VERSION_1_0
typedef enum VkMemoryHeapFlagBits {
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001,
// Provided by VK_VERSION_1_1
VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 0x00000002,
// Provided by VK_KHR_device_group_creation
VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR = VK_MEMORY_HEAP_MULTI_INSTANCE_BIT,
} VkMemoryHeapFlagBits;
-
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
specifies that the heap corresponds to device-local memory. Device-local memory may have different performance characteristics than host-local memory, and may support different memory property flags. -
VK_MEMORY_HEAP_MULTI_INSTANCE_BIT
specifies that in a logical device representing more than one physical device, there is a per-physical device instance of the heap memory. By default, an allocation from such a heap will be replicated to each physical device’s instance of the heap.
// Provided by VK_VERSION_1_0
typedef VkFlags VkMemoryHeapFlags;
VkMemoryHeapFlags
is a bitmask type for setting a mask of zero or more
VkMemoryHeapFlagBits.
The VkMemoryType
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkMemoryType {
VkMemoryPropertyFlags propertyFlags;
uint32_t heapIndex;
} VkMemoryType;
-
heapIndex
describes which memory heap this memory type corresponds to, and must be less thanmemoryHeapCount
from the VkPhysicalDeviceMemoryProperties structure. -
propertyFlags
is a bitmask of VkMemoryPropertyFlagBits of properties for this memory type.
Bits which may be set in VkMemoryType::propertyFlags
,
indicating properties of a memory type, are:
// Provided by VK_VERSION_1_0
typedef enum VkMemoryPropertyFlagBits {
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002,
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004,
VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008,
VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010,
// Provided by VK_VERSION_1_1
VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020,
// Provided by VK_AMD_device_coherent_memory
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040,
// Provided by VK_AMD_device_coherent_memory
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080,
// Provided by VK_NV_external_memory_rdma
VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100,
} VkMemoryPropertyFlagBits;
-
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
bit specifies that memory allocated with this type is the most efficient for device access. This property will be set if and only if the memory type belongs to a heap with theVK_MEMORY_HEAP_DEVICE_LOCAL_BIT
set. -
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
bit specifies that memory allocated with this type can be mapped for host access using vkMapMemory. -
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
bit specifies that the host cache management commands vkFlushMappedMemoryRanges and vkInvalidateMappedMemoryRanges are not needed to flush host writes to the device or make device writes visible to the host, respectively. -
VK_MEMORY_PROPERTY_HOST_CACHED_BIT
bit specifies that memory allocated with this type is cached on the host. Host memory accesses to uncached memory are slower than to cached memory, however uncached memory is always host coherent. -
VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
bit specifies that the memory type only allows device access to the memory. Memory types must not have bothVK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
andVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
set. Additionally, the object’s backing memory may be provided by the implementation lazily as specified in Lazily Allocated Memory. -
VK_MEMORY_PROPERTY_PROTECTED_BIT
bit specifies that the memory type only allows device access to the memory, and allows protected queue operations to access the memory. Memory types must not haveVK_MEMORY_PROPERTY_PROTECTED_BIT
set and any ofVK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
set, orVK_MEMORY_PROPERTY_HOST_COHERENT_BIT
set, orVK_MEMORY_PROPERTY_HOST_CACHED_BIT
set. -
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
bit specifies that device accesses to allocations of this memory type are automatically made available and visible. -
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD
bit specifies that memory allocated with this type is not cached on the device. Uncached device memory is always device coherent. -
VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV
bit specifies that external devices can access this memory directly.
For any memory allocated with both the
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
and the
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD
, host or device accesses
also perform automatic memory domain transfer operations, such that writes
are always automatically available and visible to both host and device
memory domains.
Note
Device coherence is a useful property for certain debugging use cases (e.g. crash analysis, where performing separate coherence actions could mean values are not reported correctly). However, device coherent accesses may be slower than equivalent accesses without device coherence, particularly if they are also device uncached. For device uncached memory in particular, repeated accesses to the same or neighbouring memory locations over a short time period (e.g. within a frame) may be slower than it would be for the equivalent cached memory type. As such, it is generally inadvisable to use device coherent or device uncached memory except when really needed. |
// Provided by VK_VERSION_1_0
typedef VkFlags VkMemoryPropertyFlags;
VkMemoryPropertyFlags
is a bitmask type for setting a mask of zero or
more VkMemoryPropertyFlagBits.
If the VkPhysicalDeviceMemoryBudgetPropertiesEXT
structure is included
in the pNext
chain of VkPhysicalDeviceMemoryProperties2, it is
filled with the current memory budgets and usages.
The VkPhysicalDeviceMemoryBudgetPropertiesEXT
structure is defined as:
// Provided by VK_EXT_memory_budget
typedef struct VkPhysicalDeviceMemoryBudgetPropertiesEXT {
VkStructureType sType;
void* pNext;
VkDeviceSize heapBudget[VK_MAX_MEMORY_HEAPS];
VkDeviceSize heapUsage[VK_MAX_MEMORY_HEAPS];
} VkPhysicalDeviceMemoryBudgetPropertiesEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
heapBudget
is an array ofVK_MAX_MEMORY_HEAPS
VkDeviceSize values in which memory budgets are returned, with one element for each memory heap. A heap’s budget is a rough estimate of how much memory the process can allocate from that heap before allocations may fail or cause performance degradation. The budget includes any currently allocated device memory. -
heapUsage
is an array ofVK_MAX_MEMORY_HEAPS
VkDeviceSize values in which memory usages are returned, with one element for each memory heap. A heap’s usage is an estimate of how much memory the process is currently using in that heap.
The values returned in this structure are not invariant.
The heapBudget
and heapUsage
values must be zero for array
elements greater than or equal to
VkPhysicalDeviceMemoryProperties::memoryHeapCount
.
The heapBudget
value must be non-zero for array elements less than
VkPhysicalDeviceMemoryProperties::memoryHeapCount
.
The heapBudget
value must be less than or equal to
VkMemoryHeap::size
for each heap.
11.2.2. Device Memory Objects
A Vulkan device operates on data in device memory via memory objects that
are represented in the API by a VkDeviceMemory
handle:
// Provided by VK_VERSION_1_0
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory)
11.2.3. Device Memory Allocation
To allocate memory objects, call:
// Provided by VK_VERSION_1_0
VkResult vkAllocateMemory(
VkDevice device,
const VkMemoryAllocateInfo* pAllocateInfo,
const VkAllocationCallbacks* pAllocator,
VkDeviceMemory* pMemory);
-
device
is the logical device that owns the memory. -
pAllocateInfo
is a pointer to a VkMemoryAllocateInfo structure describing parameters of the allocation. A successfully returned allocation must use the requested parameters — no substitution is permitted by the implementation. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter. -
pMemory
is a pointer to a VkDeviceMemory handle in which information about the allocated memory is returned.
Allocations returned by vkAllocateMemory
are guaranteed to meet any
alignment requirement of the implementation.
For example, if an implementation requires 128 byte alignment for images and
64 byte alignment for buffers, the device memory returned through this
mechanism would be 128-byte aligned.
This ensures that applications can correctly suballocate objects of
different types (with potentially different alignment requirements) in the
same memory object.
When memory is allocated, its contents are undefined with the following constraint:
-
The contents of unprotected memory must not be a function of the contents of data protected memory objects, even if those memory objects were previously freed.
Note
The contents of memory allocated by one application should not be a function of data from protected memory objects of another application, even if those memory objects were previously freed. |
The maximum number of valid memory allocations that can exist
simultaneously within a VkDevice may be restricted by implementation-
or platform-dependent limits.
The maxMemoryAllocationCount
feature describes the number of allocations that can exist simultaneously
before encountering these internal limits.
Note
For historical reasons, if |
Note
Many protected memory implementations involve complex hardware and system
software support, and often have additional and much lower limits on the
number of simultaneous protected memory allocations (from memory types with
the |
Some platforms may have a limit on the maximum size of a single allocation.
For example, certain systems may fail to create allocations with a size
greater than or equal to 4GB.
Such a limit is implementation-dependent, and if such a failure occurs then
the error VK_ERROR_OUT_OF_DEVICE_MEMORY
must be returned.
This limit is advertised in
VkPhysicalDeviceMaintenance3Properties::maxMemoryAllocationSize
.
The cumulative memory size allocated to a heap can be limited by the size
of the specified heap.
In such cases, allocated memory is tracked on a per-device and per-heap
basis.
Some platforms allow overallocation into other heaps.
The overallocation behavior can be specified through the
VK_AMD_memory_overallocation_behavior
extension.
If the
VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT::pageableDeviceLocalMemory
feature is enabled, memory allocations made from a heap that includes
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
in VkMemoryHeap::flags
may be transparently moved to host-local memory allowing multiple
applications to share device-local memory.
If there is no space left in device-local memory when this new allocation is
made, other allocations may be moved out transparently to make room.
The operating system will determine which allocations to move to
device-local memory or host-local memory based on platform-specific
criteria.
To help the operating system make good choices, the application should set
the appropriate memory priority with VkMemoryPriorityAllocateInfoEXT
and adjust it as necessary with vkSetDeviceMemoryPriorityEXT.
Higher priority allocations will moved to device-local memory first.
Memory allocations made on heaps without the
VK_MEMORY_HEAP_DEVICE_LOCAL_BIT
property will not be transparently
promoted to device-local memory by the operating system.
The VkMemoryAllocateInfo
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkMemoryAllocateInfo {
VkStructureType sType;
const void* pNext;
VkDeviceSize allocationSize;
uint32_t memoryTypeIndex;
} VkMemoryAllocateInfo;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
allocationSize
is the size of the allocation in bytes. -
memoryTypeIndex
is an index identifying a memory type from thememoryTypes
array of the VkPhysicalDeviceMemoryProperties structure.
The internal data of an allocated device memory object must include a
reference to implementation-specific resources, referred to as the memory
object’s payload.
Applications can also import and export that internal data to and from
device memory objects to share data between Vulkan instances and other
compatible APIs.
A VkMemoryAllocateInfo
structure defines a memory import operation if
its pNext
chain includes one of the following structures:
-
VkImportMemoryWin32HandleInfoKHR with a non-zero
handleType
value -
VkImportMemoryFdInfoKHR with a non-zero
handleType
value -
VkImportMemoryHostPointerInfoEXT with a non-zero
handleType
value -
VkImportAndroidHardwareBufferInfoANDROID with a non-
NULL
buffer
value -
VkImportMemoryZirconHandleInfoFUCHSIA with a non-zero
handleType
value
If the parameters define an import operation and the external handle type is
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
,
allocationSize
is ignored.
The implementation must query the size of these allocations from the OS.
Whether device memory objects constructed via a memory import operation hold a reference to their payload depends on the properties of the handle type used to perform the import, as defined below for each valid handle type. Importing memory must not modify the content of the memory. Implementations must ensure that importing memory does not enable the importing Vulkan instance to access any memory or resources in other Vulkan instances other than that corresponding to the memory object imported. Implementations must also ensure accessing imported memory which has not been initialized does not allow the importing Vulkan instance to obtain data from the exporting Vulkan instance or vice-versa.
Note
How exported and imported memory is isolated is left to the implementation, but applications should be aware that such isolation may prevent implementations from placing multiple exportable memory objects in the same physical or virtual page. Hence, applications should avoid creating many small external memory objects whenever possible. |
Importing memory must not increase overall heap usage within a system. However, it must affect the following per-process values:
-
VkPhysicalDeviceMaintenance3Properties::
maxMemoryAllocationCount
-
VkPhysicalDeviceMemoryBudgetPropertiesEXT::
heapUsage
When performing a memory import operation, it is the responsibility of the
application to ensure the external handles and their associated payloads
meet all valid usage requirements.
However, implementations must perform sufficient validation of external
handles and payloads to ensure that the operation results in a valid memory
object which will not cause program termination, device loss, queue stalls,
or corruption of other resources when used as allowed according to its
allocation parameters.
If the external handle provided does not meet these requirements, the
implementation must fail the memory import operation with the error code
VK_ERROR_INVALID_EXTERNAL_HANDLE
.
If the parameters define an export operation and the external handle type is
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
,
implementations should not strictly follow memoryTypeIndex
.
Instead, they should modify the allocation internally to use the required
memory type for the application’s given usage.
This is because for an export operation, there is currently no way for the
client to know the memory type index before allocating.
If the pNext
chain includes a VkMemoryDedicatedAllocateInfo
structure, then that structure includes a handle of the sole buffer or image
resource that the memory can be bound to.
The VkMemoryDedicatedAllocateInfo
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkMemoryDedicatedAllocateInfo {
VkStructureType sType;
const void* pNext;
VkImage image;
VkBuffer buffer;
} VkMemoryDedicatedAllocateInfo;
or the equivalent
// Provided by VK_KHR_dedicated_allocation
typedef VkMemoryDedicatedAllocateInfo VkMemoryDedicatedAllocateInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
image
is VK_NULL_HANDLE or a handle of an image which this memory will be bound to. -
buffer
is VK_NULL_HANDLE or a handle of a buffer which this memory will be bound to.
If the pNext
chain includes a
VkDedicatedAllocationMemoryAllocateInfoNV
structure, then that
structure includes a handle of the sole buffer or image resource that the
memory can be bound to.
The VkDedicatedAllocationMemoryAllocateInfoNV
structure is defined as:
// Provided by VK_NV_dedicated_allocation
typedef struct VkDedicatedAllocationMemoryAllocateInfoNV {
VkStructureType sType;
const void* pNext;
VkImage image;
VkBuffer buffer;
} VkDedicatedAllocationMemoryAllocateInfoNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
image
is VK_NULL_HANDLE or a handle of an image which this memory will be bound to. -
buffer
is VK_NULL_HANDLE or a handle of a buffer which this memory will be bound to.
If the pNext
chain includes a VkMemoryPriorityAllocateInfoEXT
structure, then that structure includes a priority for the memory.
The VkMemoryPriorityAllocateInfoEXT
structure is defined as:
// Provided by VK_EXT_memory_priority
typedef struct VkMemoryPriorityAllocateInfoEXT {
VkStructureType sType;
const void* pNext;
float priority;
} VkMemoryPriorityAllocateInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
priority
is a floating-point value between0
and1
, indicating the priority of the allocation relative to other memory allocations. Larger values are higher priority. The granularity of the priorities is implementation-dependent.
Memory allocations with higher priority may be more likely to stay in device-local memory when the system is under memory pressure.
If this structure is not included, it is as if the priority
value were
0.5
.
To modify the priority of an existing memory allocation, call:
// Provided by VK_EXT_pageable_device_local_memory
void vkSetDeviceMemoryPriorityEXT(
VkDevice device,
VkDeviceMemory memory,
float priority);
-
device
is the logical device that owns the memory. -
memory
is the VkDeviceMemory object to which the new priority will be applied. -
priority
is a floating-point value between0
and1
, indicating the priority of the allocation relative to other memory allocations. Larger values are higher priority. The granularity of the priorities is implementation-dependent.
Memory allocations with higher priority may be more likely to stay in device-local memory when the system is under memory pressure.
When allocating memory whose payload may be exported to another process or
Vulkan instance, add a VkExportMemoryAllocateInfo structure to the
pNext
chain of the VkMemoryAllocateInfo structure, specifying
the handle types that may be exported.
The VkExportMemoryAllocateInfo structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkExportMemoryAllocateInfo {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlags handleTypes;
} VkExportMemoryAllocateInfo;
or the equivalent
// Provided by VK_KHR_external_memory
typedef VkExportMemoryAllocateInfo VkExportMemoryAllocateInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleTypes
is zero or a bitmask of VkExternalMemoryHandleTypeFlagBits specifying one or more memory handle types the application can export from the resulting allocation. The application can request multiple handle types for the same allocation.
When allocating memory that may be exported to another process or Vulkan
instance, add a VkExportMemoryAllocateInfoNV structure to the
pNext
chain of the VkMemoryAllocateInfo structure, specifying
the handle types that may be exported.
The VkExportMemoryAllocateInfoNV structure is defined as:
// Provided by VK_NV_external_memory
typedef struct VkExportMemoryAllocateInfoNV {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagsNV handleTypes;
} VkExportMemoryAllocateInfoNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleTypes
is a bitmask of VkExternalMemoryHandleTypeFlagBitsNV specifying one or more memory handle types that may be exported. Multiple handle types may be requested for the same allocation as long as they are compatible, as reported by vkGetPhysicalDeviceExternalImageFormatPropertiesNV.
11.2.4. Win32 External Memory
To specify additional attributes of NT handles exported from a memory
object, add a VkExportMemoryWin32HandleInfoKHR structure to the
pNext
chain of the VkMemoryAllocateInfo structure.
The VkExportMemoryWin32HandleInfoKHR
structure is defined as:
// Provided by VK_KHR_external_memory_win32
typedef struct VkExportMemoryWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
LPCWSTR name;
} VkExportMemoryWin32HandleInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
pAttributes
is a pointer to a WindowsSECURITY_ATTRIBUTES
structure specifying security attributes of the handle. -
dwAccess
is aDWORD
specifying access rights of the handle. -
name
is a null-terminated UTF-16 string to associate with the payload referenced by NT handles exported from the created memory.
If VkExportMemoryAllocateInfo is not included in the same pNext
chain, this structure is ignored.
If VkExportMemoryAllocateInfo is included in the pNext
chain of
VkMemoryAllocateInfo with a Windows handleType
, but either
VkExportMemoryWin32HandleInfoKHR
is not included in the pNext
chain, or it is included but pAttributes
is set to NULL
, default
security descriptor values will be used, and child processes created by the
application will not inherit the handle, as described in the MSDN
documentation for “Synchronization Object Security and Access Rights”1.
Further, if the structure is not present, the access rights used depend on
the handle type.
For handles of the following types:
-
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
The implementation must ensure the access rights allow read and write access to the memory.
To import memory from a Windows handle, add a
VkImportMemoryWin32HandleInfoKHR structure to the pNext
chain of
the VkMemoryAllocateInfo structure.
The VkImportMemoryWin32HandleInfoKHR
structure is defined as:
// Provided by VK_KHR_external_memory_win32
typedef struct VkImportMemoryWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
HANDLE handle;
LPCWSTR name;
} VkImportMemoryWin32HandleInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type ofhandle
orname
. -
handle
isNULL
or the external handle to import. -
name
isNULL
or a null-terminated UTF-16 string naming the payload to import.
Importing memory object payloads from Windows handles does not transfer
ownership of the handle to the Vulkan implementation.
For handle types defined as NT handles, the application must release handle
ownership using the CloseHandle
system call when the handle is no
longer needed.
For handle types defined as NT handles, the imported memory object holds a
reference to its payload.
Note
Non-NT handle import operations do not add a reference to their associated payload. If the original object owning the payload is destroyed, all resources and handles sharing that payload will become invalid. |
Applications can import the same payload into multiple instances of Vulkan,
into the same instance from which it was exported, and multiple times into a
given Vulkan instance.
In all cases, each import operation must create a distinct
VkDeviceMemory
object.
To export a Windows handle representing the payload of a Vulkan device memory object, call:
// Provided by VK_KHR_external_memory_win32
VkResult vkGetMemoryWin32HandleKHR(
VkDevice device,
const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
HANDLE* pHandle);
-
device
is the logical device that created the device memory being exported. -
pGetWin32HandleInfo
is a pointer to a VkMemoryGetWin32HandleInfoKHR structure containing parameters of the export operation. -
pHandle
will return the Windows handle representing the payload of the device memory object.
For handle types defined as NT handles, the handles returned by
vkGetMemoryWin32HandleKHR
are owned by the application and hold a
reference to their payload.
To avoid leaking resources, the application must release ownership of them
using the CloseHandle
system call when they are no longer needed.
Note
Non-NT handle types do not add a reference to their associated payload. If the original object owning the payload is destroyed, all resources and handles sharing that payload will become invalid. |
The VkMemoryGetWin32HandleInfoKHR
structure is defined as:
// Provided by VK_KHR_external_memory_win32
typedef struct VkMemoryGetWin32HandleInfoKHR {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetWin32HandleInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memory
is the memory object from which the handle will be exported. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type of handle requested.
The properties of the handle returned depend on the value of
handleType
.
See VkExternalMemoryHandleTypeFlagBits for a description of the
properties of the defined external memory handle types.
Windows memory handles compatible with Vulkan may also be created by non-Vulkan APIs using methods beyond the scope of this specification. To determine the correct parameters to use when importing such handles, call:
// Provided by VK_KHR_external_memory_win32
VkResult vkGetMemoryWin32HandlePropertiesKHR(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
HANDLE handle,
VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties);
-
device
is the logical device that will be importinghandle
. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type of the handlehandle
. -
handle
is the handle which will be imported. -
pMemoryWin32HandleProperties
is a pointer to a VkMemoryWin32HandlePropertiesKHR structure in which properties ofhandle
are returned.
The VkMemoryWin32HandlePropertiesKHR
structure returned is defined as:
// Provided by VK_KHR_external_memory_win32
typedef struct VkMemoryWin32HandlePropertiesKHR {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
} VkMemoryWin32HandlePropertiesKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memoryTypeBits
is a bitmask containing one bit set for every memory type which the specified windows handle can be imported as.
When VkExportMemoryAllocateInfoNV::handleTypes
includes
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV
, add a
VkExportMemoryWin32HandleInfoNV
structure to the pNext
chain of
the VkExportMemoryAllocateInfoNV structure to specify security
attributes and access rights for the memory object’s external handle.
The VkExportMemoryWin32HandleInfoNV
structure is defined as:
// Provided by VK_NV_external_memory_win32
typedef struct VkExportMemoryWin32HandleInfoNV {
VkStructureType sType;
const void* pNext;
const SECURITY_ATTRIBUTES* pAttributes;
DWORD dwAccess;
} VkExportMemoryWin32HandleInfoNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
pAttributes
is a pointer to a WindowsSECURITY_ATTRIBUTES
structure specifying security attributes of the handle. -
dwAccess
is aDWORD
specifying access rights of the handle.
If this structure is not present, or if pAttributes
is set to NULL
,
default security descriptor values will be used, and child processes created
by the application will not inherit the handle, as described in the MSDN
documentation for “Synchronization Object Security and Access Rights”1.
Further, if the structure is not present, the access rights will be
DXGI_SHARED_RESOURCE_READ
| DXGI_SHARED_RESOURCE_WRITE
To import memory created on the same physical device but outside of the
current Vulkan instance, add a VkImportMemoryWin32HandleInfoNV
structure to the pNext
chain of the VkMemoryAllocateInfo
structure, specifying a handle to and the type of the memory.
The VkImportMemoryWin32HandleInfoNV
structure is defined as:
// Provided by VK_NV_external_memory_win32
typedef struct VkImportMemoryWin32HandleInfoNV {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagsNV handleType;
HANDLE handle;
} VkImportMemoryWin32HandleInfoNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleType
is0
or a VkExternalMemoryHandleTypeFlagBitsNV value specifying the type of memory handle inhandle
. -
handle
is a WindowsHANDLE
referring to the memory.
If handleType
is 0
, this structure is ignored by consumers of the
VkMemoryAllocateInfo structure it is chained from.
Bits which can be set in handleType
are:
Possible values of VkImportMemoryWin32HandleInfoNV::handleType
,
specifying the type of an external memory handle, are:
// Provided by VK_NV_external_memory_capabilities
typedef enum VkExternalMemoryHandleTypeFlagBitsNV {
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV = 0x00000001,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV = 0x00000002,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV = 0x00000004,
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV = 0x00000008,
} VkExternalMemoryHandleTypeFlagBitsNV;
-
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV
specifies a handle to memory returned by vkGetMemoryWin32HandleNV. -
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV
specifies a handle to memory returned by vkGetMemoryWin32HandleNV, or one duplicated from such a handle usingDuplicateHandle()
. -
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV
specifies a valid NT handle to memory returned byIDXGIResource1::CreateSharedHandle
, or a handle duplicated from such a handle usingDuplicateHandle()
. -
VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV
specifies a handle to memory returned byIDXGIResource::GetSharedHandle()
.
editing-note
(Jon) If additional (non-Win32) bits are added to the possible memory types,
this type should move to the |
// Provided by VK_NV_external_memory_capabilities
typedef VkFlags VkExternalMemoryHandleTypeFlagsNV;
VkExternalMemoryHandleTypeFlagsNV
is a bitmask type for setting a mask
of zero or more VkExternalMemoryHandleTypeFlagBitsNV.
To retrieve the handle corresponding to a device memory object created with
VkExportMemoryAllocateInfoNV::handleTypes
set to include
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV
or
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV
, call:
// Provided by VK_NV_external_memory_win32
VkResult vkGetMemoryWin32HandleNV(
VkDevice device,
VkDeviceMemory memory,
VkExternalMemoryHandleTypeFlagsNV handleType,
HANDLE* pHandle);
-
device
is the logical device that owns the memory. -
memory
is the VkDeviceMemory object. -
handleType
is a bitmask of VkExternalMemoryHandleTypeFlagBitsNV containing a single bit specifying the type of handle requested. -
handle
is a pointer to a WindowsHANDLE
in which the handle is returned.
11.2.5. File Descriptor External Memory
To import memory from a POSIX file descriptor handle, add a
VkImportMemoryFdInfoKHR structure to the pNext
chain of the
VkMemoryAllocateInfo structure.
The VkImportMemoryFdInfoKHR
structure is defined as:
// Provided by VK_KHR_external_memory_fd
typedef struct VkImportMemoryFdInfoKHR {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
int fd;
} VkImportMemoryFdInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the handle type offd
. -
fd
is the external handle to import.
Importing memory from a file descriptor transfers ownership of the file descriptor from the application to the Vulkan implementation. The application must not perform any operations on the file descriptor after a successful import. The imported memory object holds a reference to its payload.
Applications can import the same payload into multiple instances of Vulkan,
into the same instance from which it was exported, and multiple times into a
given Vulkan instance.
In all cases, each import operation must create a distinct
VkDeviceMemory
object.
To export a POSIX file descriptor referencing the payload of a Vulkan device memory object, call:
// Provided by VK_KHR_external_memory_fd
VkResult vkGetMemoryFdKHR(
VkDevice device,
const VkMemoryGetFdInfoKHR* pGetFdInfo,
int* pFd);
-
device
is the logical device that created the device memory being exported. -
pGetFdInfo
is a pointer to a VkMemoryGetFdInfoKHR structure containing parameters of the export operation. -
pFd
will return a file descriptor referencing the payload of the device memory object.
Each call to vkGetMemoryFdKHR
must create a new file descriptor
holding a reference to the memory object’s payload and transfer ownership of
the file descriptor to the application.
To avoid leaking resources, the application must release ownership of the
file descriptor using the close
system call when it is no longer
needed, or by importing a Vulkan memory object from it.
Where supported by the operating system, the implementation must set the
file descriptor to be closed automatically when an execve
system call
is made.
The VkMemoryGetFdInfoKHR
structure is defined as:
// Provided by VK_KHR_external_memory_fd
typedef struct VkMemoryGetFdInfoKHR {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetFdInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memory
is the memory object from which the handle will be exported. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type of handle requested.
The properties of the file descriptor exported depend on the value of
handleType
.
See VkExternalMemoryHandleTypeFlagBits for a description of the
properties of the defined external memory handle types.
Note
The size of the exported file may be larger than the size requested by
VkMemoryAllocateInfo:: |
POSIX file descriptor memory handles compatible with Vulkan may also be created by non-Vulkan APIs using methods beyond the scope of this specification. To determine the correct parameters to use when importing such handles, call:
// Provided by VK_KHR_external_memory_fd
VkResult vkGetMemoryFdPropertiesKHR(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
int fd,
VkMemoryFdPropertiesKHR* pMemoryFdProperties);
-
device
is the logical device that will be importingfd
. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type of the handlefd
. -
fd
is the handle which will be imported. -
pMemoryFdProperties
is a pointer to a VkMemoryFdPropertiesKHR structure in which the properties of the handlefd
are returned.
The VkMemoryFdPropertiesKHR
structure returned is defined as:
// Provided by VK_KHR_external_memory_fd
typedef struct VkMemoryFdPropertiesKHR {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
} VkMemoryFdPropertiesKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memoryTypeBits
is a bitmask containing one bit set for every memory type which the specified file descriptor can be imported as.
11.2.6. Host External Memory
To import memory from a host pointer, add a
VkImportMemoryHostPointerInfoEXT structure to the pNext
chain of
the VkMemoryAllocateInfo structure.
The VkImportMemoryHostPointerInfoEXT
structure is defined as:
// Provided by VK_EXT_external_memory_host
typedef struct VkImportMemoryHostPointerInfoEXT {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
void* pHostPointer;
} VkImportMemoryHostPointerInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the handle type. -
pHostPointer
is the host pointer to import from.
Importing memory from a host pointer shares ownership of the memory between the host and the Vulkan implementation. The application can continue to access the memory through the host pointer but it is the application’s responsibility to synchronize device and non-device access to the payload as defined in Host Access to Device Memory Objects.
Applications can import the same payload into multiple instances of Vulkan and multiple times into a given Vulkan instance. However, implementations may fail to import the same payload multiple times into a given physical device due to platform constraints.
Importing memory from a particular host pointer may not be possible due to
additional platform-specific restrictions beyond the scope of this
specification in which case the implementation must fail the memory import
operation with the error code VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR
.
Whether device memory objects imported from a host pointer hold a reference to their payload is undefined. As such, the application must ensure that the imported memory range remains valid and accessible for the lifetime of the imported memory object.
To determine the correct parameters to use when importing host pointers, call:
// Provided by VK_EXT_external_memory_host
VkResult vkGetMemoryHostPointerPropertiesEXT(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
const void* pHostPointer,
VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties);
-
device
is the logical device that will be importingpHostPointer
. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type of the handlepHostPointer
. -
pHostPointer
is the host pointer to import from. -
pMemoryHostPointerProperties
is a pointer to a VkMemoryHostPointerPropertiesEXT structure in which the host pointer properties are returned.
The VkMemoryHostPointerPropertiesEXT
structure is defined as:
// Provided by VK_EXT_external_memory_host
typedef struct VkMemoryHostPointerPropertiesEXT {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
} VkMemoryHostPointerPropertiesEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memoryTypeBits
is a bitmask containing one bit set for every memory type which the specified host pointer can be imported as.
The value returned by memoryTypeBits
must only include bits that
identify memory types which are host visible.
11.2.7. Android Hardware Buffer External Memory
To import memory created outside of the current Vulkan instance from an
Android hardware buffer, add a
VkImportAndroidHardwareBufferInfoANDROID
structure to the pNext
chain of the VkMemoryAllocateInfo structure.
The VkImportAndroidHardwareBufferInfoANDROID
structure is defined as:
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
typedef struct VkImportAndroidHardwareBufferInfoANDROID {
VkStructureType sType;
const void* pNext;
struct AHardwareBuffer* buffer;
} VkImportAndroidHardwareBufferInfoANDROID;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
buffer
is the Android hardware buffer to import.
If the vkAllocateMemory command succeeds, the implementation must acquire a reference to the imported hardware buffer, which it must release when the device memory object is freed. If the command fails, the implementation must not retain a reference.
To export an Android hardware buffer referencing the payload of a Vulkan device memory object, call:
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
VkResult vkGetMemoryAndroidHardwareBufferANDROID(
VkDevice device,
const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
struct AHardwareBuffer** pBuffer);
-
device
is the logical device that created the device memory being exported. -
pInfo
is a pointer to a VkMemoryGetAndroidHardwareBufferInfoANDROID structure containing parameters of the export operation. -
pBuffer
will return an Android hardware buffer referencing the payload of the device memory object.
Each call to vkGetMemoryAndroidHardwareBufferANDROID
must return an
Android hardware buffer with a new reference acquired in addition to the
reference held by the VkDeviceMemory.
To avoid leaking resources, the application must release the reference by
calling AHardwareBuffer_release
when it is no longer needed.
When called with the same handle in
VkMemoryGetAndroidHardwareBufferInfoANDROID::memory
,
vkGetMemoryAndroidHardwareBufferANDROID
must return the same Android
hardware buffer object.
If the device memory was created by importing an Android hardware buffer,
vkGetMemoryAndroidHardwareBufferANDROID
must return that same Android
hardware buffer object.
The VkMemoryGetAndroidHardwareBufferInfoANDROID
structure is defined
as:
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
typedef struct VkMemoryGetAndroidHardwareBufferInfoANDROID {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
} VkMemoryGetAndroidHardwareBufferInfoANDROID;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memory
is the memory object from which the Android hardware buffer will be exported.
To determine the memory parameters to use when importing an Android hardware buffer, call:
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
VkResult vkGetAndroidHardwareBufferPropertiesANDROID(
VkDevice device,
const struct AHardwareBuffer* buffer,
VkAndroidHardwareBufferPropertiesANDROID* pProperties);
-
device
is the logical device that will be importingbuffer
. -
buffer
is the Android hardware buffer which will be imported. -
pProperties
is a pointer to a VkAndroidHardwareBufferPropertiesANDROID structure in which the properties ofbuffer
are returned.
The VkAndroidHardwareBufferPropertiesANDROID
structure returned is
defined as:
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
typedef struct VkAndroidHardwareBufferPropertiesANDROID {
VkStructureType sType;
void* pNext;
VkDeviceSize allocationSize;
uint32_t memoryTypeBits;
} VkAndroidHardwareBufferPropertiesANDROID;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
allocationSize
is the size of the external memory -
memoryTypeBits
is a bitmask containing one bit set for every memory type which the specified Android hardware buffer can be imported as.
To obtain format properties of an Android hardware buffer, include a
VkAndroidHardwareBufferFormatPropertiesANDROID
structure in the
pNext
chain of the VkAndroidHardwareBufferPropertiesANDROID
structure passed to vkGetAndroidHardwareBufferPropertiesANDROID.
This structure is defined as:
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
typedef struct VkAndroidHardwareBufferFormatPropertiesANDROID {
VkStructureType sType;
void* pNext;
VkFormat format;
uint64_t externalFormat;
VkFormatFeatureFlags formatFeatures;
VkComponentMapping samplerYcbcrConversionComponents;
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
VkSamplerYcbcrRange suggestedYcbcrRange;
VkChromaLocation suggestedXChromaOffset;
VkChromaLocation suggestedYChromaOffset;
} VkAndroidHardwareBufferFormatPropertiesANDROID;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
format
is the Vulkan format corresponding to the Android hardware buffer’s format, orVK_FORMAT_UNDEFINED
if there is not an equivalent Vulkan format. -
externalFormat
is an implementation-defined external format identifier for use with VkExternalFormatANDROID. It must not be zero. -
formatFeatures
describes the capabilities of this external format when used with an image bound to memory imported frombuffer
. -
samplerYcbcrConversionComponents
is the component swizzle that should be used in VkSamplerYcbcrConversionCreateInfo. -
suggestedYcbcrModel
is a suggested color model to use in the VkSamplerYcbcrConversionCreateInfo. -
suggestedYcbcrRange
is a suggested numerical value range to use in VkSamplerYcbcrConversionCreateInfo. -
suggestedXChromaOffset
is a suggested X chroma offset to use in VkSamplerYcbcrConversionCreateInfo. -
suggestedYChromaOffset
is a suggested Y chroma offset to use in VkSamplerYcbcrConversionCreateInfo.
If the Android hardware buffer has one of the formats listed in the
Format Equivalence
table, then format
must have the equivalent Vulkan format listed in
the table.
Otherwise, format
may be VK_FORMAT_UNDEFINED
, indicating the
Android hardware buffer can only be used with an external format.
The formatFeatures
member must include
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
and at least one of
VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT
or
VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT
, and should include
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT
and
VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT
.
Note
The |
Android hardware buffers with the same external format must have the same
support for VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT
,
VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT
,
VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT
,
VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT
,
VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT
,
and
VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT
.
in formatFeatures
.
Other format features may differ between Android hardware buffers that have
the same external format.
This allows applications to use the same VkSamplerYcbcrConversion
object (and samplers and pipelines created from them) for any Android
hardware buffers that have the same external format.
If format
is not VK_FORMAT_UNDEFINED
, then the value of
samplerYcbcrConversionComponents
must be valid when used as the
components
member of VkSamplerYcbcrConversionCreateInfo with
that format.
If format
is VK_FORMAT_UNDEFINED
, all members of
samplerYcbcrConversionComponents
must be the
identity swizzle.
Implementations may not always be able to determine the color model,
numerical range, or chroma offsets of the image contents, so the values in
VkAndroidHardwareBufferFormatPropertiesANDROID
are only suggestions.
Applications should treat these values as sensible defaults to use in the
absence of more reliable information obtained through some other means.
If the underlying physical device is also usable via OpenGL ES with the
GL_OES_EGL_image_external
extension, the implementation should suggest values that will produce
similar sampled values as would be obtained by sampling the same external
image via samplerExternalOES
in OpenGL ES using equivalent sampler
parameters.
Note
Since
|
The format properties of an Android hardware buffer can be obtained by
including a VkAndroidHardwareBufferFormatProperties2ANDROID
structure
in the pNext
chain of the
VkAndroidHardwareBufferPropertiesANDROID structure passed to
vkGetAndroidHardwareBufferPropertiesANDROID.
This structure is defined as:
// Provided by VK_KHR_format_feature_flags2 with VK_ANDROID_external_memory_android_hardware_buffer
typedef struct VkAndroidHardwareBufferFormatProperties2ANDROID {
VkStructureType sType;
void* pNext;
VkFormat format;
uint64_t externalFormat;
VkFormatFeatureFlags2 formatFeatures;
VkComponentMapping samplerYcbcrConversionComponents;
VkSamplerYcbcrModelConversion suggestedYcbcrModel;
VkSamplerYcbcrRange suggestedYcbcrRange;
VkChromaLocation suggestedXChromaOffset;
VkChromaLocation suggestedYChromaOffset;
} VkAndroidHardwareBufferFormatProperties2ANDROID;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
format
is the Vulkan format corresponding to the Android hardware buffer’s format, orVK_FORMAT_UNDEFINED
if there is not an equivalent Vulkan format. -
externalFormat
is an implementation-defined external format identifier for use with VkExternalFormatANDROID. It must not be zero. -
formatFeatures
describes the capabilities of this external format when used with an image bound to memory imported frombuffer
. -
samplerYcbcrConversionComponents
is the component swizzle that should be used in VkSamplerYcbcrConversionCreateInfo. -
suggestedYcbcrModel
is a suggested color model to use in the VkSamplerYcbcrConversionCreateInfo. -
suggestedYcbcrRange
is a suggested numerical value range to use in VkSamplerYcbcrConversionCreateInfo. -
suggestedXChromaOffset
is a suggested X chroma offset to use in VkSamplerYcbcrConversionCreateInfo. -
suggestedYChromaOffset
is a suggested Y chroma offset to use in VkSamplerYcbcrConversionCreateInfo.
The bits reported in formatFeatures
must include the bits reported in
the corresponding fields of
VkAndroidHardwareBufferFormatPropertiesANDROID
::formatFeatures
.
11.2.8. Remote Device External Memory
To export an address representing the payload of a Vulkan device memory object accessible by remote devices, call:
// Provided by VK_NV_external_memory_rdma
VkResult vkGetMemoryRemoteAddressNV(
VkDevice device,
const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo,
VkRemoteAddressNV* pAddress);
-
device
is the logical device that created the device memory being exported. -
pMemoryGetRemoteAddressInfo
is a pointer to a VkMemoryGetRemoteAddressInfoNV structure containing parameters of the export operation. -
pAddress
is a pointer to a VkRemoteAddressNV value in which an address representing the payload of the device memory object is returned.
More communication may be required between the kernel-mode drivers of the devices involved. This information is out of scope of this documentation and should be requested from the vendors of the devices.
The VkMemoryGetRemoteAddressInfoNV
structure is defined as:
// Provided by VK_NV_external_memory_rdma
typedef struct VkMemoryGetRemoteAddressInfoNV {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetRemoteAddressInfoNV;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memory
is the memory object from which the remote accessible address will be exported. -
handleType
is the type of handle requested.
VkRemoteAddressNV represents an address of a memory object
accessible by remote devices, as returned in
vkGetMemoryRemoteAddressNV::pAddress
.
// Provided by VK_NV_external_memory_rdma
typedef void* VkRemoteAddressNV;
11.2.9. Fuchsia External Memory
On Fuchsia, when allocating memory that may be imported from another
device, process or Vulkan instance, add a
VkImportMemoryZirconHandleInfoFUCHSIA structure to the pNext
chain of the VkMemoryAllocateInfo structure.
External memory on Fuchsia is imported and exported using VMO handles of
type zx_handle_t
.
VMO handles to external memory are canonically obtained from Fuchsia’s
Sysmem service or from syscalls such as zx_vmo_create
().
VMO handles for import can also be obtained by exporting them from another
Vulkan instance as described in exporting
fuchsia device memory.
Importing VMO handles to the Vulkan instance transfers ownership of the handle to the instance from the application. The application must not perform any operations on the handle after successful import.
Applications can import the same underlying memory into multiple instances
of Vulkan, into the same instance from which it was exported, and multiple
times into a given Vulkan instance.
In all cases, each import operation must create a distinct
VkDeviceMemory
object.
Importing Fuchsia External Memory
The VkImportMemoryZirconHandleInfoFUCHSIA
structure is defined as:
// Provided by VK_FUCHSIA_external_memory
typedef struct VkImportMemoryZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkExternalMemoryHandleTypeFlagBits handleType;
zx_handle_t handle;
} VkImportMemoryZirconHandleInfoFUCHSIA;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type ofhandle
. -
handle
is azx_handle_t
(Zircon) handle to the external memory.
To obtain the memoryTypeIndex for the VkMemoryAllocateInfo structure,
call vkGetMemoryZirconHandlePropertiesFUCHSIA
:
// Provided by VK_FUCHSIA_external_memory
VkResult vkGetMemoryZirconHandlePropertiesFUCHSIA(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
zx_handle_t zirconHandle,
VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties);
-
device
is the VkDevice. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type ofzirconHandle
-
zirconHandle
is azx_handle_t
(Zircon) handle to the external resource. -
pMemoryZirconHandleProperties
is a pointer to a VkMemoryZirconHandlePropertiesFUCHSIA structure in which the result will be stored.
The VkMemoryZirconHandlePropertiesFUCHSIA
structure is defined as:
// Provided by VK_FUCHSIA_external_memory
typedef struct VkMemoryZirconHandlePropertiesFUCHSIA {
VkStructureType sType;
void* pNext;
uint32_t memoryTypeBits;
} VkMemoryZirconHandlePropertiesFUCHSIA;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memoryTypeBits
a bitmask containing one bit set for every memory type which the specified handle can be imported as.
With pMemoryZirconHandleProperties
now successfully populated by
vkGetMemoryZirconHandlePropertiesFUCHSIA, assign the
VkMemoryAllocateInfo memoryTypeIndex field to a memory type which has
a bit set in the VkMemoryZirconHandlePropertiesFUCHSIA memoryTypeBits
field.
Exporting Fuchsia Device Memory
Similar to importing, exporting a VMO handle from Vulkan transfers ownership
of the handle from the Vulkan instance to the application.
The application is responsible for closing the handle with
zx_handle_close
() when it is no longer in use.
To export device memory as a Zircon handle that can be used by another instance, device, or process, the handle to the VkDeviceMemory must be retrieved using vkGetMemoryZirconHandleFUCHSIA:
// Provided by VK_FUCHSIA_external_memory
VkResult vkGetMemoryZirconHandleFUCHSIA(
VkDevice device,
const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo,
zx_handle_t* pZirconHandle);
-
device
is the VkDevice. -
pGetZirconHandleInfo
is a pointer to a VkMemoryGetZirconHandleInfoFUCHSIA structure. -
pZirconHandle
is a pointer to azx_handle_t
which holds the resulting Zircon handle.
VkMemoryGetZirconHandleInfoFUCHSIA
is defined as:
// Provided by VK_FUCHSIA_external_memory
typedef struct VkMemoryGetZirconHandleInfoFUCHSIA {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkExternalMemoryHandleTypeFlagBits handleType;
} VkMemoryGetZirconHandleInfoFUCHSIA;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memory
the VkDeviceMemory being exported. -
handleType
is a VkExternalMemoryHandleTypeFlagBits value specifying the type of the handle pointed to by vkGetMemoryZirconHandleFUCHSIA::pZirconHandle
.
With the result pZirconHandle
now obtained, the memory properties for
the handle can be retrieved using
vkGetMemoryZirconHandlePropertiesFUCHSIA as documented above
substituting the dereferenced, retrieved pZirconHandle
in for the
zirconHandle
argument.
11.2.10. Metal Objects
A Vulkan implementation that is layered on top of Metal on Apple device
platform, and implements the VK_EXT_metal_objects
extension,
supports the ability to import and export the underlying Metal objects
associated with specific Vulkan objects.
The underlying Metal objects associated with certain Vulkan objects can be
exported from those Vulkan objects using the pNext
chain of the
VkExportMetalObjectsInfoEXT parameter of the
vkExportMetalObjectsEXT command.
An VkDeviceMemory object can be allocated on an existing
MTLBuffer
object, by including the MTLBuffer
object in a
VkImportMetalBufferInfoEXT structure in the pNext
chain of the
VkMemoryAllocateInfo structure in the vkAllocateMemory command.
A new VkImage object can be created on an existing IOSurface
object, or one or more existing Metal MTLTexture
objects, by including
those Metal objects in either VkImportMetalIOSurfaceInfoEXT or
VkImportMetalTextureInfoEXT structures in the pNext
chain of the
VkImageCreateInfo structure in the vkCreateImage command.
To export Metal objects from Vulkan objects, the app must first indicate
the intention to do so during the creation of the Vulkan object, by
including one or more VkExportMetalObjectCreateInfoEXT structures in
the pNext
chain of the VkInstanceCreateInfo,
VkMemoryAllocateInfo, VkImageCreateInfo,
VkImageViewCreateInfo, VkBufferViewCreateInfo,
VkSemaphoreCreateInfo, or VkEventCreateInfo, in the
corresponding Vulkan object creation command.
The VkExportMetalObjectCreateInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkExportMetalObjectCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkExportMetalObjectTypeFlagBitsEXT exportObjectType;
} VkExportMetalObjectCreateInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
exportObjectType
is a VkExportMetalObjectTypeFlagBitsEXT indicating the type of Metal object that the application may request to be exported from the Vulkan object.
Bits which indicate the types of Metal objects that may be exported from a corresponding Vulkan object are:
// Provided by VK_EXT_metal_objects
typedef enum VkExportMetalObjectTypeFlagBitsEXT {
VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT = 0x00000001,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT = 0x00000002,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT = 0x00000004,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT = 0x00000008,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT = 0x00000010,
VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT = 0x00000020,
} VkExportMetalObjectTypeFlagBitsEXT;
-
VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT
indicates a MetalMTLDevice
may be exported. -
VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT
indicates a MetalMTLCommandQueue
may be exported. -
VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT
indicates a MetalMTLBuffer
may be exported. -
VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT
indicates a MetalMTLTexture
may be exported. -
VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT
indicates a MetalIOSurface
may be exported. -
VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT
indicates a MetalMTLSharedEvent
may be exported.
// Provided by VK_EXT_metal_objects
typedef VkFlags VkExportMetalObjectTypeFlagsEXT;
VkExportMetalObjectTypeFlagsEXT
is a bitmask type for setting a mask
of zero or more VkExportMetalObjectTypeFlagBitsEXT.
To export Metal objects that underlie Vulkan objects, call:
// Provided by VK_EXT_metal_objects
void vkExportMetalObjectsEXT(
VkDevice device,
VkExportMetalObjectsInfoEXT* pMetalObjectsInfo);
-
device
is the device that created the Vulkan objects. -
pMetalObjectsInfo
is a pointer to a VkExportMetalObjectsInfoEXT structure whosepNext
chain contains structures, each identifying a Vulkan object and providing a pointer through which the Metal object will be returned.
The VkExportMetalObjectsInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkExportMetalObjectsInfoEXT {
VkStructureType sType;
const void* pNext;
} VkExportMetalObjectsInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure.
To export the Metal MTLDevice
object underlying the
VkPhysicalDevice associated with a VkDevice object, include a
VkExportMetalDeviceInfoEXT
structure in the pNext
chain of the
pMetalObjectsInfo
parameter of a vkExportMetalObjectsEXT call.
The VkExportMetalDeviceInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkExportMetalDeviceInfoEXT {
VkStructureType sType;
const void* pNext;
MTLDevice_id mtlDevice;
} VkExportMetalDeviceInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
mtlDevice
is the Metalid<MTLDevice>
object underlying the VkPhysicalDevice associated with the VkDevice object identified in the call. The implementation will return theMTLDevice
in this member, or it will returnNULL
if noMTLDevice
could be found underlying the VkPhysicalDevice object.
The type id<MTLDevice>
is defined in Apple’s Metal framework, but to
remove an unnecessary compile time dependency, an incomplete type definition
of MTLDevice_id is provided in the Vulkan headers:
// Provided by VK_EXT_metal_objects
#ifdef __OBJC__
@protocol MTLDevice;
typedef id<MTLDevice> MTLDevice_id;
#else
typedef void* MTLDevice_id;
#endif
To export the Metal MTLCommandQueue
object underlying a VkQueue
object, include a VkExportMetalCommandQueueInfoEXT
structure in the
pNext
chain of the pMetalObjectsInfo
parameter of a
vkExportMetalObjectsEXT call.
The VkExportMetalCommandQueueInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkExportMetalCommandQueueInfoEXT {
VkStructureType sType;
const void* pNext;
VkQueue queue;
MTLCommandQueue_id mtlCommandQueue;
} VkExportMetalCommandQueueInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
queue
is a VkQueue. -
mtlCommandQueue
is the Metalid<MTLCommandQueue>
object underlying the VkQueue object inqueue
. The implementation will return theMTLCommandQueue
in this member, or it will returnNULL
if noMTLCommandQueue
could be found underlying the VkQueue object.
The type id<MTLCommandQueue>
is defined in Apple’s Metal framework, but to
remove an unnecessary compile time dependency, an incomplete type definition
of MTLCommandQueue_id is provided in the Vulkan headers:
// Provided by VK_EXT_metal_objects
#ifdef __OBJC__
@protocol MTLCommandQueue;
typedef id<MTLCommandQueue> MTLCommandQueue_id;
#else
typedef void* MTLCommandQueue_id;
#endif
To export the Metal MTLBuffer
object underlying a VkDeviceMemory
object, include a VkExportMetalBufferInfoEXT
structure in the
pNext
chain of the pMetalObjectsInfo
parameter of a
vkExportMetalObjectsEXT call.
The VkExportMetalBufferInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkExportMetalBufferInfoEXT {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
MTLBuffer_id mtlBuffer;
} VkExportMetalBufferInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memory
is a VkDeviceMemory. -
mtlBuffer
is the Metalid<MTLBuffer>
object underlying the VkDeviceMemory object inmemory
. The implementation will return theMTLBuffer
in this member, or it will returnNULL
if noMTLBuffer
could be found underlying the VkDeviceMemory object.
To import a Metal MTLBuffer
object to underlie a VkDeviceMemory
object, include a VkImportMetalBufferInfoEXT
structure in the
pNext
chain of the VkMemoryAllocateInfo structure in a
vkAllocateMemory command.
The VkImportMetalBufferInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkImportMetalBufferInfoEXT {
VkStructureType sType;
const void* pNext;
MTLBuffer_id mtlBuffer;
} VkImportMetalBufferInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
mtlBuffer
is the Metalid<MTLBuffer>
object that is to underlie the VkDeviceMemory.
The app must ensure that the configuration of the id<MTLBuffer>
object is
compatible with the configuration of the VkDeviceMemory.
Failure to do so results in undefined behavior.
The type id<MTLBuffer>
is defined in Apple’s Metal framework, but to
remove an unnecessary compile time dependency, an incomplete type definition
of MTLBuffer_id is provided in the Vulkan headers:
// Provided by VK_EXT_metal_objects
#ifdef __OBJC__
@protocol MTLBuffer;
typedef id<MTLBuffer> MTLBuffer_id;
#else
typedef void* MTLBuffer_id;
#endif
To export a Metal MTLTexture
object underlying a VkImage,
VkImageView, or VkBufferView object, include a
VkExportMetalTextureInfoEXT
structure in the pNext
chain of the
pMetalObjectsInfo
parameter of a vkExportMetalObjectsEXT call.
The VkExportMetalTextureInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkExportMetalTextureInfoEXT {
VkStructureType sType;
const void* pNext;
VkImage image;
VkImageView imageView;
VkBufferView bufferView;
VkImageAspectFlagBits plane;
MTLTexture_id mtlTexture;
} VkExportMetalTextureInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
image
is VK_NULL_HANDLE or a VkImage. -
imageView
is VK_NULL_HANDLE or a VkImageView. -
bufferView
is VK_NULL_HANDLE or a VkBufferView. -
plane
indicates the plane of a multi-planar VkImage or VkImageView. -
mtlTexture
is the Metalid<MTLTexture>
object underlying the VkImage, VkImageView, or VkBufferView object inimage
,imageView
, orbufferView
, respectively, at the plane indicated inaspectMask
. The implementation will return theMTLTexture
in this member, or it will returnNULL
if noMTLTexture
could be found underlying the VkImage, VkImageView, or VkBufferView object, at the plane indicated inaspectMask
.
To import one or more existing Metal MTLTexture
objects to underlie a
VkImage object, include one or more VkImportMetalTextureInfoEXT
structures in the pNext
chain of the VkImageCreateInfo structure
in a vkCreateImage command.
The VkImportMetalTextureInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkImportMetalTextureInfoEXT {
VkStructureType sType;
const void* pNext;
VkImageAspectFlagBits plane;
MTLTexture_id mtlTexture;
} VkImportMetalTextureInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
plane
indicates the plane of the VkImage that theid<MTLTexture>
object should be attached to. -
mtlTexture
is a the Metalid<MTLTexture>
object that is to underlie the VkImage plane.
The type id<MTLTexture>
is defined in Apple’s Metal framework, but to
remove an unnecessary compile time dependency, an incomplete type definition
of MTLTexture_id is provided in the Vulkan headers:
// Provided by VK_EXT_metal_objects
#ifdef __OBJC__
@protocol MTLTexture;
typedef id<MTLTexture> MTLTexture_id;
#else
typedef void* MTLTexture_id;
#endif
To export the Metal IOSurfaceRef object underlying a VkImage
object, include a VkExportMetalIOSurfaceInfoEXT
structure in the
pNext
chain of the pMetalObjectsInfo
parameter of a
vkExportMetalObjectsEXT call.
The VkExportMetalIOSurfaceInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkExportMetalIOSurfaceInfoEXT {
VkStructureType sType;
const void* pNext;
VkImage image;
IOSurfaceRef ioSurface;
} VkExportMetalIOSurfaceInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
image
is a VkImage. -
ioSurface
is the Metal IOSurfaceRef object underlying the VkImage object inimage
. The implementation will return the IOSurfaceRef in this member, or it will returnNULL
if no IOSurfaceRef could be found underlying the VkImage object.
To import, or create, a Metal IOSurfaceRef object to underlie a
VkImage object, include a VkImportMetalIOSurfaceInfoEXT
structure in the pNext
chain of the VkImageCreateInfo structure
in a vkCreateImage command.
The VkImportMetalIOSurfaceInfoEXT
structure is defined as:
// Provided by VK_EXT_metal_objects
typedef struct VkImportMetalIOSurfaceInfoEXT {
VkStructureType sType;
const void* pNext;
IOSurfaceRef ioSurface;
} VkImportMetalIOSurfaceInfoEXT;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
ioSurface
is VK_NULL_HANDLE or the Metal IOSurfaceRef object that is to underlie the VkImage.
If ioSurface
is not VK_NULL_HANDLE, it will be used to underlie
the VkImage.
If ioSurface
is VK_NULL_HANDLE, the implementation will create a
new IOSurface
to underlie the VkImage.
If provided, the app must ensure that the configuration of the IOSurfaceRef object is compatible with the configuration of the VkImage. Failure to do so results in undefined behavior.
The type IOSurfaceRef is defined in Apple’s CoreGraphics framework, but to remove an unnecessary compile time dependency, an incomplete type definition of IOSurfaceRef is provided in the Vulkan headers:
// Provided by VK_EXT_metal_objects
typedef struct __IOSurface* IOSurfaceRef;
To export the Metal MTLSharedEvent
object underlying a
VkSemaphore or VkEvent object, include a
VkExportMetalSharedEventInfoEXT
structure in the pNext
chain of
the pMetalObjectsInfo
parameter of a vkExportMetalObjectsEXT
call.
The VkExportMetalSharedEventInfoEXT
structure is defined as:
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
semaphore
is VK_NULL_HANDLE or a VkSemaphore. -
event
is VK_NULL_HANDLE or a VkEvent. -
mtlSharedEvent
is the Metalid<MTLSharedEvent>
object underlying the VkSemaphore or VkEvent object insemaphore
orevent
, respectively. The implementation will return theMTLSharedEvent
in this member, or it will returnNULL
if noMTLSharedEvent
could be found underlying the VkSemaphore or VkEvent object.
To import a Metal id<MTLSharedEvent>
object to underlie a
VkSemaphore or VkEvent object, include a
VkImportMetalSharedEventInfoEXT
structure in the pNext
chain of
the VkSemaphoreCreateInfo or VkEventCreateInfo structure in a
vkCreateSemaphore or vkCreateEvent command, respectively.
The VkImportMetalSharedEventInfoEXT
structure is defined as:
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
mtlSharedEvent
is the Metalid<MTLSharedEvent>
object that is to underlie the VkSemaphore or VkEvent.
If the pNext
chain of the VkSemaphoreCreateInfo structure
includes both VkImportMetalSharedEventInfoEXT
and
VkSemaphoreTypeCreateInfo, the signaledValue
property of the
imported id<MTLSharedEvent>
object will be set to initialValue
of
VkSemaphoreTypeCreateInfo.
The type id<MTLSharedEvent>
is defined in Apple’s Metal framework, but to
remove an unnecessary compile time dependency, an incomplete type definition
of MTLSharedEvent_id is provided in the Vulkan headers:
11.2.11. Device Group Memory Allocations
If the pNext
chain of VkMemoryAllocateInfo includes a
VkMemoryAllocateFlagsInfo
structure, then that structure includes
flags and a device mask controlling how many instances of the memory will be
allocated.
The VkMemoryAllocateFlagsInfo
structure is defined as:
// Provided by VK_VERSION_1_1
typedef struct VkMemoryAllocateFlagsInfo {
VkStructureType sType;
const void* pNext;
VkMemoryAllocateFlags flags;
uint32_t deviceMask;
} VkMemoryAllocateFlagsInfo;
or the equivalent
// Provided by VK_KHR_device_group
typedef VkMemoryAllocateFlagsInfo VkMemoryAllocateFlagsInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
flags
is a bitmask of VkMemoryAllocateFlagBits controlling the allocation. -
deviceMask
is a mask of physical devices in the logical device, indicating that memory must be allocated on each device in the mask, ifVK_MEMORY_ALLOCATE_DEVICE_MASK_BIT
is set inflags
.
If VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT
is not set, the number of
instances allocated depends on whether
VK_MEMORY_HEAP_MULTI_INSTANCE_BIT
is set in the memory heap.
If VK_MEMORY_HEAP_MULTI_INSTANCE_BIT
is set, then memory is allocated
for every physical device in the logical device (as if deviceMask
has
bits set for all device indices).
If VK_MEMORY_HEAP_MULTI_INSTANCE_BIT
is not set, then a single
instance of memory is allocated (as if deviceMask
is set to one).
On some implementations, allocations from a multi-instance heap may consume
memory on all physical devices even if the deviceMask
excludes some
devices.
If VkPhysicalDeviceGroupProperties::subsetAllocation
is
VK_TRUE
, then memory is only consumed for the devices in the device
mask.
Note
In practice, most allocations on a multi-instance heap will be allocated across all physical devices. Unicast allocation support is an optional optimization for a minority of allocations. |
Bits which can be set in VkMemoryAllocateFlagsInfo::flags
,
controlling device memory allocation, are:
// Provided by VK_VERSION_1_1
typedef enum VkMemoryAllocateFlagBits {
VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001,
// Provided by VK_VERSION_1_2
VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002,
// Provided by VK_VERSION_1_2
VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004,
// Provided by VK_KHR_device_group
VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT,
// Provided by VK_KHR_buffer_device_address
VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT,
// Provided by VK_KHR_buffer_device_address
VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT,
} VkMemoryAllocateFlagBits;
or the equivalent
// Provided by VK_KHR_device_group
typedef VkMemoryAllocateFlagBits VkMemoryAllocateFlagBitsKHR;
-
VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT
specifies that memory will be allocated for the devices in VkMemoryAllocateFlagsInfo::deviceMask
. -
VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT
specifies that the memory can be attached to a buffer object created with theVK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
bit set inusage
, and that the memory handle can be used to retrieve an opaque address via vkGetDeviceMemoryOpaqueCaptureAddress. -
VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT
specifies that the memory’s address can be saved and reused on a subsequent run (e.g. for trace capture and replay), see VkBufferOpaqueCaptureAddressCreateInfo for more detail.
// Provided by VK_VERSION_1_1
typedef VkFlags VkMemoryAllocateFlags;
or the equivalent
// Provided by VK_KHR_device_group
typedef VkMemoryAllocateFlags VkMemoryAllocateFlagsKHR;
VkMemoryAllocateFlags
is a bitmask type for setting a mask of zero or
more VkMemoryAllocateFlagBits.
11.2.12. Opaque Capture Address Allocation
To request a specific device address for a memory allocation, add a
VkMemoryOpaqueCaptureAddressAllocateInfo structure to the pNext
chain of the VkMemoryAllocateInfo structure.
The VkMemoryOpaqueCaptureAddressAllocateInfo
structure is defined as:
// Provided by VK_VERSION_1_2
typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo {
VkStructureType sType;
const void* pNext;
uint64_t opaqueCaptureAddress;
} VkMemoryOpaqueCaptureAddressAllocateInfo;
or the equivalent
// Provided by VK_KHR_buffer_device_address
typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
opaqueCaptureAddress
is the opaque capture address requested for the memory allocation.
If opaqueCaptureAddress
is zero, no specific address is requested.
If opaqueCaptureAddress
is not zero, it should be an address
retrieved from vkGetDeviceMemoryOpaqueCaptureAddress on an identically
created memory allocation on the same implementation.
Note
In most cases, it is expected that a non-zero This is, however, not a strict requirement because trace capture/replay tools may need to adjust memory allocation parameters for imported memory. |
If this structure is not present, it is as if opaqueCaptureAddress
is
zero.
11.2.13. Freeing Device Memory
To free a memory object, call:
// Provided by VK_VERSION_1_0
void vkFreeMemory(
VkDevice device,
VkDeviceMemory memory,
const VkAllocationCallbacks* pAllocator);
-
device
is the logical device that owns the memory. -
memory
is the VkDeviceMemory object to be freed. -
pAllocator
controls host memory allocation as described in the Memory Allocation chapter.
Before freeing a memory object, an application must ensure the memory object is no longer in use by the device — for example by command buffers in the pending state. Memory can be freed whilst still bound to resources, but those resources must not be used afterwards. Freeing a memory object releases the reference it held, if any, to its payload. If there are still any bound images or buffers, the memory object’s payload may not be immediately released by the implementation, but must be released by the time all bound images and buffers have been destroyed. Once all references to a payload are released, it is returned to the heap from which it was allocated.
How memory objects are bound to Images and Buffers is described in detail in the Resource Memory Association section.
If a memory object is mapped at the time it is freed, it is implicitly unmapped.
Note
As described below, host writes are not implicitly flushed when the memory object is unmapped, but the implementation must guarantee that writes that have not been flushed do not affect any other memory. |
11.2.14. Host Access to Device Memory Objects
Memory objects created with vkAllocateMemory are not directly host accessible.
Memory objects created with the memory property
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
are considered mappable.
Memory objects must be mappable in order to be successfully mapped on the
host.
To retrieve a host virtual address pointer to a region of a mappable memory object, call:
// Provided by VK_VERSION_1_0
VkResult vkMapMemory(
VkDevice device,
VkDeviceMemory memory,
VkDeviceSize offset,
VkDeviceSize size,
VkMemoryMapFlags flags,
void** ppData);
-
device
is the logical device that owns the memory. -
memory
is the VkDeviceMemory object to be mapped. -
offset
is a zero-based byte offset from the beginning of the memory object. -
size
is the size of the memory range to map, orVK_WHOLE_SIZE
to map fromoffset
to the end of the allocation. -
flags
is reserved for future use. -
ppData
is a pointer to avoid*
variable in which a host-accessible pointer to the beginning of the mapped range is returned. This pointer minusoffset
must be aligned to at least VkPhysicalDeviceLimits::minMemoryMapAlignment
.
After a successful call to vkMapMemory
the memory object memory
is considered to be currently host mapped.
Note
It is an application error to call |
Note
|
vkMapMemory
does not check whether the device memory is currently in
use before returning the host-accessible pointer.
The application must guarantee that any previously submitted command that
writes to this range has completed before the host reads from or writes to
that range, and that any previously submitted command that reads from that
range has completed before the host writes to that region (see
here for details on fulfilling
such a guarantee).
If the device memory was allocated without the
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
set, these guarantees must be
made for an extended range: the application must round down the start of
the range to the nearest multiple of
VkPhysicalDeviceLimits::nonCoherentAtomSize
, and round the end
of the range up to the nearest multiple of
VkPhysicalDeviceLimits::nonCoherentAtomSize
.
While a range of device memory is host mapped, the application is responsible for synchronizing both device and host access to that memory range.
Note
It is important for the application developer to become meticulously familiar with all of the mechanisms described in the chapter on Synchronization and Cache Control as they are crucial to maintaining memory access ordering. |
// Provided by VK_VERSION_1_0
typedef VkFlags VkMemoryMapFlags;
VkMemoryMapFlags
is a bitmask type for setting a mask, but is
currently reserved for future use.
Two commands are provided to enable applications to work with non-coherent
memory allocations: vkFlushMappedMemoryRanges
and
vkInvalidateMappedMemoryRanges
.
Note
If the memory object was created with the
|
Note
While memory objects imported from a handle type of
|
After a successful call to vkMapMemory
the memory object memory
is considered to be currently host mapped.
To flush ranges of non-coherent memory from the host caches, call:
// Provided by VK_VERSION_1_0
VkResult vkFlushMappedMemoryRanges(
VkDevice device,
uint32_t memoryRangeCount,
const VkMappedMemoryRange* pMemoryRanges);
-
device
is the logical device that owns the memory ranges. -
memoryRangeCount
is the length of thepMemoryRanges
array. -
pMemoryRanges
is a pointer to an array of VkMappedMemoryRange structures describing the memory ranges to flush.
vkFlushMappedMemoryRanges
guarantees that host writes to the memory
ranges described by pMemoryRanges
are made available to the host
memory domain, such that they can be made available to the device memory
domain via memory
domain operations using the VK_ACCESS_HOST_WRITE_BIT
access type.
Within each range described by pMemoryRanges
, each set of
nonCoherentAtomSize
bytes in that range is flushed if any byte in that
set has been written by the host since it was first host mapped, or the last
time it was flushed.
If pMemoryRanges
includes sets of nonCoherentAtomSize
bytes
where no bytes have been written by the host, those bytes must not be
flushed.
Unmapping non-coherent memory does not implicitly flush the host mapped memory, and host writes that have not been flushed may not ever be visible to the device. However, implementations must ensure that writes that have not been flushed do not become visible to any other memory.
Note
The above guarantee avoids a potential memory corruption in scenarios where host writes to a mapped memory object have not been flushed before the memory is unmapped (or freed), and the virtual address range is subsequently reused for a different mapping (or memory allocation). |
To invalidate ranges of non-coherent memory from the host caches, call:
// Provided by VK_VERSION_1_0
VkResult vkInvalidateMappedMemoryRanges(
VkDevice device,
uint32_t memoryRangeCount,
const VkMappedMemoryRange* pMemoryRanges);
-
device
is the logical device that owns the memory ranges. -
memoryRangeCount
is the length of thepMemoryRanges
array. -
pMemoryRanges
is a pointer to an array of VkMappedMemoryRange structures describing the memory ranges to invalidate.
vkInvalidateMappedMemoryRanges
guarantees that device writes to the
memory ranges described by pMemoryRanges
, which have been made
available to the host memory domain using the VK_ACCESS_HOST_WRITE_BIT
and VK_ACCESS_HOST_READ_BIT
access
types, are made visible to the host.
If a range of non-coherent memory is written by the host and then
invalidated without first being flushed, its contents are undefined.
Within each range described by pMemoryRanges
, each set of
nonCoherentAtomSize
bytes in that range is invalidated if any byte in
that set has been written by the device since it was first host mapped, or
the last time it was invalidated.
Note
Mapping non-coherent memory does not implicitly invalidate that memory. |
The VkMappedMemoryRange
structure is defined as:
// Provided by VK_VERSION_1_0
typedef struct VkMappedMemoryRange {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkDeviceSize offset;
VkDeviceSize size;
} VkMappedMemoryRange;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memory
is the memory object to which this range belongs. -
offset
is the zero-based byte offset from the beginning of the memory object. -
size
is either the size of range, orVK_WHOLE_SIZE
to affect the range fromoffset
to the end of the current mapping of the allocation.
To unmap a memory object once host access to it is no longer needed by the application, call:
// Provided by VK_VERSION_1_0
void vkUnmapMemory(
VkDevice device,
VkDeviceMemory memory);
-
device
is the logical device that owns the memory. -
memory
is the memory object to be unmapped.
11.2.15. Lazily Allocated Memory
If the memory object is allocated from a heap with the
VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
bit set, that object’s backing
memory may be provided by the implementation lazily.
The actual committed size of the memory may initially be as small as zero
(or as large as the requested size), and monotonically increases as
additional memory is needed.
A memory type with this flag set is only allowed to be bound to a
VkImage
whose usage flags include
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
.
Note
Using lazily allocated memory objects for framebuffer attachments that are not needed once a render pass instance has completed may allow some implementations to never allocate memory for such attachments. |
To determine the amount of lazily-allocated memory that is currently committed for a memory object, call:
// Provided by VK_VERSION_1_0
void vkGetDeviceMemoryCommitment(
VkDevice device,
VkDeviceMemory memory,
VkDeviceSize* pCommittedMemoryInBytes);
-
device
is the logical device that owns the memory. -
memory
is the memory object being queried. -
pCommittedMemoryInBytes
is a pointer to a VkDeviceSize value in which the number of bytes currently committed is returned, on success.
The implementation may update the commitment at any time, and the value returned by this query may be out of date.
The implementation guarantees to allocate any committed memory from the
heapIndex
indicated by the memory type that the memory object was
created with.
11.2.16. Protected Memory
Protected memory divides device memory into protected device memory and unprotected device memory.
Protected memory adds the following concepts:
-
Memory:
-
Unprotected device memory, which can be visible to the device and can be visible to the host
-
Protected device memory, which can be visible to the device but must not be visible to the host
-
-
Resources:
-
Unprotected images and unprotected buffers, to which unprotected memory can be bound
-
Protected images and protected buffers, to which protected memory can be bound
-
-
Command buffers:
-
Unprotected command buffers, which can be submitted to a device queue to execute unprotected queue operations
-
Protected command buffers, which can be submitted to a protected-capable device queue to execute protected queue operations
-
-
Device queues:
-
Unprotected device queues, to which unprotected command buffers can be submitted
-
Protected-capable device queues, to which unprotected command buffers or protected command buffers can be submitted
-
-
Queue submissions
-
Unprotected queue submissions, through which unprotected command buffers can be submitted
-
Protected queue submissions, through which protected command buffers can be submitted
-
-
Queue operations
-
Unprotected queue operations
-
Protected queue operations
-
Note
When the |
Protected Memory Access Rules
If VkPhysicalDeviceProtectedMemoryProperties::protectedNoFault
is VK_FALSE
, applications must not perform any of the following
operations:
-
Write to unprotected memory within protected queue operations.
-
Access protected memory within protected queue operations other than in framebuffer-space pipeline stages, the compute shader stage, or the transfer stage.
-
Perform a query within protected queue operations.
If VkPhysicalDeviceProtectedMemoryProperties::protectedNoFault
is VK_TRUE
, these operations are valid, but reads will return
undefined values, and writes will either be dropped or store undefined
values.
Additionally, indirect operations must not be performed within protected queue operations.
Whether these operations are valid or not, or if any other invalid usage is performed, the implementation must guarantee that:
-
Protected device memory must never be visible to the host.
-
Values written to unprotected device memory must not be a function of values from protected memory.
11.2.17. External Memory Handle Types
Android Hardware Buffer
Android’s NDK defines AHardwareBuffer objects, which represent
device memory that is shareable across processes and that can be accessed
by a variety of media APIs and the hardware used to implement them.
These Android hardware buffer objects may be imported into
VkDeviceMemory objects for access via Vulkan, or exported from Vulkan.
An VkImage or VkBuffer can be bound to the imported or exported
VkDeviceMemory object if it is created with
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
.
To remove an unnecessary compile time dependency, an incomplete type definition of AHardwareBuffer is provided in the Vulkan headers:
// Provided by VK_ANDROID_external_memory_android_hardware_buffer
struct AHardwareBuffer;
The actual AHardwareBuffer type is defined in Android NDK headers.
Note
The NDK format, usage, and size/dimensions of an AHardwareBuffer
object can be obtained with the |
Android hardware buffer objects are reference-counted using Android NDK
functions outside of the scope of this specification.
A VkDeviceMemory imported from an Android hardware buffer or that can
be exported to an Android hardware buffer must acquire a reference to its
AHardwareBuffer object, and must release this reference when the
device memory is freed.
During the host execution of a Vulkan command that has an Android hardware
buffer as a parameter (including indirect parameters via pNext
chains), the application must not decrement the Android hardware buffer’s
reference count to zero.
Android hardware buffers can be mapped and unmapped for CPU access using the NDK functions. These lock and unlock APIs are considered to acquire and release ownership of the Android hardware buffer, and applications must follow the rules described in External Resource Sharing to transfer ownership between the Vulkan instance and these native APIs.
Android hardware buffers can be shared with external APIs and Vulkan instances on the same device, and also with foreign devices. When transferring ownership of the Android hardware buffer, the external and foreign special queue families described in Queue Family Ownership Transfer are not identical. All APIs which produce or consume Android hardware buffers are considered to use foreign devices, except OpenGL ES contexts and Vulkan logical devices that have matching device and driver UUIDs. Implementations may treat a transfer to or from the foreign queue family as if it were a transfer to or from the external queue family when the Android hardware buffer’s usage only permits it to be used on the same physical device.
Android Hardware Buffer Optimal Usages
Vulkan buffer and image usage flags do not correspond exactly to Android
hardware buffer usage flags.
When allocating Android hardware buffers with non-Vulkan APIs, if any
AHARDWAREBUFFER_USAGE_GPU_*
usage bits are included, by default the
allocator must allocate the memory in such a way that it supports Vulkan
usages and creation flags in the
usage equivalence table
which do not have Android hardware buffer equivalents.
An VkAndroidHardwareBufferUsageANDROID structure can be included in
the pNext
chain of a VkImageFormatProperties2 structure passed
to vkGetPhysicalDeviceImageFormatProperties2 to obtain optimal Android
hardware buffer usage flags for specific Vulkan resource creation
parameters.
Some usage flags returned by these commands are required based on the input
parameters, but additional vendor-specific usage flags
(AHARDWAREBUFFER_USAGE_VENDOR_*
) may also be returned.
Any Android hardware buffer allocated with these vendor-specific usage flags
and imported to Vulkan must only be bound to resources created with
parameters that are a subset of the parameters used to obtain the Android
hardware buffer usage, since the memory may have been allocated in a way
incompatible with other parameters.
If an Android hardware buffer is successfully allocated with additional
non-vendor-specific usage flags in addition to the recommended usage, it
must support being used in the same ways as an Android hardware buffer
allocated with only the recommended usage, and also in ways indicated by the
additional usage.
Android Hardware Buffer External Formats
Android hardware buffers may represent images using implementation-specific formats, layouts, color models, etc., which do not have Vulkan equivalents. Such external formats are commonly used by external image sources such as video decoders or cameras. Vulkan can import Android hardware buffers that have external formats, but since the image contents are in an undiscoverable and possibly proprietary representation, images with external formats must only be used as sampled images, must only be sampled with a sampler that has Y′CBCR conversion enabled, and must have optimal tiling.
Images that will be backed by an Android hardware buffer can use an
external format by setting VkImageCreateInfo::format
to
VK_FORMAT_UNDEFINED
and including a VkExternalFormatANDROID
structure in the pNext
chain.
Images can be created with an external format even if the Android hardware
buffer has a format which has an
equivalent Vulkan format
to enable consistent handling of images from sources that might use either
category of format.
However, all images created with an external format are subject to the valid
usage requirements associated with external formats, even if the Android
hardware buffer’s format has a Vulkan equivalent.
The external format of an Android hardware buffer can be obtained by
passing a VkAndroidHardwareBufferFormatPropertiesANDROID structure to
vkGetAndroidHardwareBufferPropertiesANDROID.
Android Hardware Buffer Image Resources
Android hardware buffers have intrinsic width, height, format, and usage
properties, so Vulkan images bound to memory imported from an Android
hardware buffer must use dedicated allocations:
VkMemoryDedicatedRequirements
::requiresDedicatedAllocation
must
be VK_TRUE
for images created with
VkExternalMemoryImageCreateInfo::handleTypes
that includes
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
.
When creating an image that will be bound to an imported Android hardware
buffer, the image creation parameters must be equivalent to the
AHardwareBuffer properties as described by the valid usage of
VkMemoryAllocateInfo.
Similarly, device memory allocated for a dedicated image must not be
exported to an Android hardware buffer until it has been bound to that
image, and the implementation must return an Android hardware buffer with
properties derived from the image:
-
The
width
andheight
members ofAHardwareBuffer_Desc
must be the same as thewidth
andheight
members of VkImageCreateInfo::extent
, respectively. -
The
layers
member ofAHardwareBuffer_Desc
must be the same as thearrayLayers
member of VkImageCreateInfo. -
The
format
member ofAHardwareBuffer_Desc
must be equivalent to VkImageCreateInfo::format
as defined by AHardwareBuffer Format Equivalence. -
The
usage
member ofAHardwareBuffer_Desc
must include bits corresponding to bits included in VkImageCreateInfo::usage
and VkImageCreateInfo::flags
where such a correspondence exists according to AHardwareBuffer Usage Equivalence. It may also include additional usage bits, including vendor-specific usages. Presence of vendor usage bits may make the Android hardware buffer only usable in ways indicated by the image creation parameters, even when used outside Vulkan, in a similar way that allocating the Android hardware buffer with usage returned in VkAndroidHardwareBufferUsageANDROID does.
Implementations may support fewer combinations of image creation parameters
for images with Android hardware buffer external handle type than for
non-external images.
Support for a given set of parameters can be determined by passing
VkExternalImageFormatProperties to
vkGetPhysicalDeviceImageFormatProperties2 with handleType
set to
VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
.
Any Android hardware buffer successfully allocated outside Vulkan with usage
that includes AHARDWAREBUFFER_USAGE_GPU_*
must be supported when using
equivalent Vulkan image parameters.
If a given choice of image parameters are supported for import, they can
also be used to create an image and memory that will be exported to an
Android hardware buffer.
AHardwareBuffer Format | Vulkan Format |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AHardwareBuffer Usage | Vulkan Usage or Creation Flag |
---|---|
None |
|
None |
|
|
|
|
|
|
|
|
|
|
|
|
None 2 |
|
|
None |
|
None |
|
|
|
- 1
-
Vulkan does not differentiate between
AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM
andAHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM
: they both behave asVK_FORMAT_R8G8B8A8_UNORM
. After an external entity writes to aAHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM
Android hardware buffer, the values read by Vulkan from the X/A component are undefined. To emulate the traditional behavior of the X component during sampling or blending, applications should useVK_COMPONENT_SWIZZLE_ONE
in image view component mappings andVK_BLEND_FACTOR_ONE
in color blend factors. There is no way to avoid copying these undefined values when copying from such an image to another image or buffer. - 2
-
The
AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE
flag does not correspond to a Vulkan image usage or creation flag. Instead, its presence indicates that the Android hardware buffer contains a complete mipmap chain, and its absence indicates that the Android hardware buffer contains only a single mip level. - 3
-
Only image usages valid for the format are valid. It would be invalid to take a Android Hardware Buffer with a format of
AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM
that has aAHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER
usage and try to create an image withVK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
. - 4
-
In combination with a hardware buffer format other than
BLOB
.
Note
When using |
Android Hardware Buffer Buffer Resources
Android hardware buffers with a format of AHARDWAREBUFFER_FORMAT_BLOB
and usage that includes AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER
can be
used as the backing store for VkBuffer objects.
Such Android hardware buffers have a size in bytes specified by their
width
; height
and layers
are both 1
.
Unlike images, buffer resources backed by Android hardware buffers do not require dedicated allocations.
Exported AHardwareBuffer objects that do not have dedicated images
must have a format of AHARDWAREBUFFER_FORMAT_BLOB
, usage must include
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER
, width
must equal the
device memory allocation size, and height
and layers
must be 1
.
11.2.18. Peer Memory Features
Peer memory is memory that is allocated for a given physical device and then bound to a resource and accessed by a different physical device, in a logical device that represents multiple physical devices. Some ways of reading and writing peer memory may not be supported by a device.
To determine how peer memory can be accessed, call:
// Provided by VK_VERSION_1_1
void vkGetDeviceGroupPeerMemoryFeatures(
VkDevice device,
uint32_t heapIndex,
uint32_t localDeviceIndex,
uint32_t remoteDeviceIndex,
VkPeerMemoryFeatureFlags* pPeerMemoryFeatures);
or the equivalent command
// Provided by VK_KHR_device_group
void vkGetDeviceGroupPeerMemoryFeaturesKHR(
VkDevice device,
uint32_t heapIndex,
uint32_t localDeviceIndex,
uint32_t remoteDeviceIndex,
VkPeerMemoryFeatureFlags* pPeerMemoryFeatures);
-
device
is the logical device that owns the memory. -
heapIndex
is the index of the memory heap from which the memory is allocated. -
localDeviceIndex
is the device index of the physical device that performs the memory access. -
remoteDeviceIndex
is the device index of the physical device that the memory is allocated for. -
pPeerMemoryFeatures
is a pointer to a VkPeerMemoryFeatureFlags bitmask indicating which types of memory accesses are supported for the combination of heap, local, and remote devices.
Bits which may be set in
vkGetDeviceGroupPeerMemoryFeatures::pPeerMemoryFeatures
,
indicating supported peer memory features, are:
// Provided by VK_VERSION_1_1
typedef enum VkPeerMemoryFeatureFlagBits {
VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT = 0x00000001,
VK_PEER_MEMORY_FEATURE_COPY_DST_BIT = 0x00000002,
VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT = 0x00000004,
VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 0x00000008,
// Provided by VK_KHR_device_group
VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT,
// Provided by VK_KHR_device_group
VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT,
// Provided by VK_KHR_device_group
VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT,
// Provided by VK_KHR_device_group
VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT,
} VkPeerMemoryFeatureFlagBits;
or the equivalent
// Provided by VK_KHR_device_group
typedef VkPeerMemoryFeatureFlagBits VkPeerMemoryFeatureFlagBitsKHR;
-
VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT
specifies that the memory can be accessed as the source of anyvkCmdCopy*
command. -
VK_PEER_MEMORY_FEATURE_COPY_DST_BIT
specifies that the memory can be accessed as the destination of anyvkCmdCopy*
command. -
VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT
specifies that the memory can be read as any memory access type. -
VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT
specifies that the memory can be written as any memory access type. Shader atomics are considered to be writes.
Note
The peer memory features of a memory heap also apply to any accesses that may be performed during image layout transitions. |
VK_PEER_MEMORY_FEATURE_COPY_DST_BIT
must be supported for all host
local heaps and for at least one device-local memory heap.
If a device does not support a peer memory feature, it is still valid to use a resource that includes both local and peer memory bindings with the corresponding access type as long as only the local bindings are actually accessed. For example, an application doing split-frame rendering would use framebuffer attachments that include both local and peer memory bindings, but would scissor the rendering to only update local memory.
// Provided by VK_VERSION_1_1
typedef VkFlags VkPeerMemoryFeatureFlags;
or the equivalent
// Provided by VK_KHR_device_group
typedef VkPeerMemoryFeatureFlags VkPeerMemoryFeatureFlagsKHR;
VkPeerMemoryFeatureFlags
is a bitmask type for setting a mask of zero
or more VkPeerMemoryFeatureFlagBits.
11.2.19. Opaque Capture Address Query
To query a 64-bit opaque capture address value from a memory object, call:
// Provided by VK_VERSION_1_2
uint64_t vkGetDeviceMemoryOpaqueCaptureAddress(
VkDevice device,
const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
or the equivalent command
// Provided by VK_KHR_buffer_device_address
uint64_t vkGetDeviceMemoryOpaqueCaptureAddressKHR(
VkDevice device,
const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo);
-
device
is the logical device that the memory object was allocated on. -
pInfo
is a pointer to a VkDeviceMemoryOpaqueCaptureAddressInfo structure specifying the memory object to retrieve an address for.
The 64-bit return value is an opaque address representing the start of
pInfo->memory
.
If the memory object was allocated with a non-zero value of
VkMemoryOpaqueCaptureAddressAllocateInfo::opaqueCaptureAddress
,
the return value must be the same address.
Note
The expected usage for these opaque addresses is only for trace capture/replay tools to store these addresses in a trace and subsequently specify them during replay. |
The VkDeviceMemoryOpaqueCaptureAddressInfo
structure is defined as:
// Provided by VK_VERSION_1_2
typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
} VkDeviceMemoryOpaqueCaptureAddressInfo;
or the equivalent
// Provided by VK_KHR_buffer_device_address
typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR;
-
sType
is a VkStructureType value identifying this structure. -
pNext
isNULL
or a pointer to a structure extending this structure. -
memory
specifies the memory whose address is being queried.