Vulkan-Docs/doc/specs/vulkan/chapters/memory.txt

2223 lines
93 KiB
Plaintext

// Copyright (c) 2015-2017 Khronos Group. This work is licensed under a
// Creative Commons Attribution 4.0 International License; see
// http://creativecommons.org/licenses/by/4.0/
[[memory]]
= Memory Allocation
Vulkan memory is broken up into two categories, _host memory_ and _device
memory_.
[[memory-host]]
== Host Memory
Host memory is memory needed by the Vulkan implementation for
non-device-visible storage.
This storage may: be used for e.g. internal software structures.
[[memory-allocation]]
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.
[open,refpage='VkAllocationCallbacks',desc='Structure containing callback function pointers for memory allocation',type='structs']
--
Allocators are provided by the application as a pointer to a
sname:VkAllocationCallbacks structure:
include::../api/structs/VkAllocationCallbacks.txt[]
* pname:pUserData is a value to be interpreted by the implementation of
the callbacks.
When any of the callbacks in sname:VkAllocationCallbacks 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.
* pname:pfnAllocation is a pointer to an application-defined memory
allocation function of type tlink:PFN_vkAllocationFunction.
* pname:pfnReallocation is a pointer to an application-defined memory
reallocation function of type tlink:PFN_vkReallocationFunction.
* pname:pfnFree is a pointer to an application-defined memory free
function of type tlink:PFN_vkFreeFunction.
* pname:pfnInternalAllocation is a pointer to an application-defined
function that is called by the implementation when the implementation
makes internal allocations, and it is of type
tlink:PFN_vkInternalAllocationNotification.
* pname:pfnInternalFree is a pointer to an application-defined function
that is called by the implementation when the implementation frees
internal allocations, and it is of type
tlink:PFN_vkInternalFreeNotification.
.Valid Usage
****
* [[VUID-VkAllocationCallbacks-pfnAllocation-00632]]
pname:pfnAllocation must: be a valid pointer to a valid user-defined
tlink:PFN_vkAllocationFunction
* [[VUID-VkAllocationCallbacks-pfnReallocation-00633]]
pname:pfnReallocation must: be a valid pointer to a valid user-defined
tlink:PFN_vkReallocationFunction
* [[VUID-VkAllocationCallbacks-pfnFree-00634]]
pname:pfnFree must: be a valid pointer to a valid user-defined
tlink:PFN_vkFreeFunction
* [[VUID-VkAllocationCallbacks-pfnInternalAllocation-00635]]
If either of pname:pfnInternalAllocation or pname:pfnInternalFree is not
`NULL`, both must: be valid callbacks
****
include::../validity/structs/VkAllocationCallbacks.txt[]
--
[open,refpage='PFN_vkAllocationFunction',desc='Application-defined memory allocation function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnAllocation is:
include::../api/funcpointers/PFN_vkAllocationFunction.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:size is the size in bytes of the requested allocation.
* pname:alignment is the requested alignment of the allocation in bytes
and must: be a power of two.
* pname:allocationScope is a elink:VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described <<memory-host-allocation-scope,here>>.
[[vkAllocationFunction_return_rules]]
If pname: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 pname:size bytes, and with the pointer value
being a multiple of pname:alignment.
[NOTE]
.Note
====
Correct Vulkan operation cannot: be assumed if the application does not
follow these rules.
For example, pname:pfnAllocation (or pname:pfnReallocation) could cause
termination of running Vulkan instance(s) on a failed allocation for
debugging purposes, either directly or indirectly.
In these circumstances, it cannot: be assumed that any part of any affected
slink:VkInstance objects are going to operate correctly (even
flink:vkDestroyInstance), and the application must: ensure it cleans up
properly via other means (e.g. process termination).
====
If pname: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 run-time error, and generate
ename:VK_ERROR_OUT_OF_HOST_MEMORY at the appropriate time for the command in
which the condition was detected, as described in <<fundamentals-errorcodes,
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 ename:VK_ERROR_OUT_OF_HOST_MEMORY as a result of this failed
allocation.
--
[open,refpage='PFN_vkReallocationFunction',desc='Application-defined memory reallocation function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnReallocation is:
include::../api/funcpointers/PFN_vkReallocationFunction.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:pOriginal must: be either `NULL` or a pointer previously returned
by pname:pfnReallocation or pname:pfnAllocation of the same allocator.
* pname:size is the size in bytes of the requested allocation.
* pname:alignment is the requested alignment of the allocation in bytes
and must: be a power of two.
* pname:allocationScope is a elink:VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described <<memory-host-allocation-scope,here>>.
pname:pfnReallocation must: return an allocation with enough space for
pname:size bytes, and the contents of the original allocation from bytes
zero to [eq]#min(original size, new size) - 1# must: be preserved in the
returned allocation.
If pname: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 pname:pOriginal is `NULL`, then pname:pfnReallocation must: behave
equivalently to a call to tlink:PFN_vkAllocationFunction with the same
parameter values (without pname:pOriginal).
If pname:size is zero, then pname:pfnReallocation must: behave equivalently
to a call to tlink:PFN_vkFreeFunction with the same pname:pUserData
parameter value, and pname:pMemory equal to pname:pOriginal.
If pname:pOriginal is non-`NULL`, the implementation must: ensure that
pname:alignment is equal to the pname:alignment used to originally allocate
pname:pOriginal.
If this function fails and pname:pOriginal is non-`NULL` the application
must: not free the old allocation.
pname:pfnReallocation must: follow the same
<<vkAllocationFunction_return_rules, rules for return values as
tname:PFN_vkAllocationFunction>>.
--
[open,refpage='PFN_vkFreeFunction',desc='Application-defined memory free function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnFree is:
include::../api/funcpointers/PFN_vkFreeFunction.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:pMemory is the allocation to be freed.
pname:pMemory may: be `NULL`, which the callback must: handle safely.
If pname:pMemory is non-`NULL`, it must: be a pointer previously allocated
by pname:pfnAllocation or pname:pfnReallocation.
The application should: free this memory.
--
[open,refpage='PFN_vkInternalAllocationNotification',desc='Application-defined memory allocation notification function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnInternalAllocation is:
include::../api/funcpointers/PFN_vkInternalAllocationNotification.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:size is the requested size of an allocation.
* pname:allocationType is a elink:VkInternalAllocationType value
specifying the requested type of an allocation.
* pname:allocationScope is a elink:VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described <<memory-host-allocation-scope,here>>.
This is a purely informational callback.
--
[open,refpage='PFN_vkInternalFreeNotification',desc='Application-defined memory free notification function',type='funcpointers',xrefs='VkAllocationCallbacks']
--
The type of pname:pfnInternalFree is:
include::../api/funcpointers/PFN_vkInternalFreeNotification.txt[]
* pname:pUserData is the value specified for
slink:VkAllocationCallbacks::pname:pUserData in the allocator specified
by the application.
* pname:size is the requested size of an allocation.
* pname:allocationType is a elink:VkInternalAllocationType value
specifying the requested type of an allocation.
* pname:allocationScope is a elink:VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described <<memory-host-allocation-scope,here>>.
--
[open,refpage='VkSystemAllocationScope',desc='Allocation scope',type='enums',xrefs='VkAllocationCallbacks']
--
[[memory-host-allocation-scope]]
Each allocation has an _allocation scope_ which defines its lifetime and
which object it is associated with.
Possible values passed to the pname:allocationScope parameter of the
callback functions specified by slink:VkAllocationCallbacks, indicating the
allocation scope, are:
include::../api/enums/VkSystemAllocationScope.txt[]
* ename:VK_SYSTEM_ALLOCATION_SCOPE_COMMAND specifies that the allocation
is scoped to the duration of the Vulkan command.
* ename:VK_SYSTEM_ALLOCATION_SCOPE_OBJECT specifies that the allocation is
scoped to the lifetime of the Vulkan object that is being created or
used.
* ename:VK_SYSTEM_ALLOCATION_SCOPE_CACHE specifies that the allocation is
scoped to the lifetime of a sname:VkPipelineCache
ifdef::VK_EXT_validation_cache[]
or sname:VkValidationCacheEXT
endif::VK_EXT_validation_cache[]
object.
* ename:VK_SYSTEM_ALLOCATION_SCOPE_DEVICE specifies that the allocation is
scoped to the lifetime of the Vulkan device.
* ename: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
ename:VK_SYSTEM_ALLOCATION_SCOPE_OBJECT or
ename: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 ename: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 parent sname:VkDevice has an allocator it will be
used, else if the parent sname:VkInstance has an allocator it will be
used.
Else,
* If an allocation is associated with an object of type
ifdef::VK_EXT_validation_cache[]
sname:VkValidationCacheEXT or
endif::VK_EXT_validation_cache[]
sname:VkPipelineCache, the allocator will use the
ename:VK_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 sname:VkDevice or sname:VkInstance, the allocator will use an
allocation scope of ename:VK_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 ename: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 ename: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, pname:pfnInternalAllocation will be
called.
Upon freeing executable memory, pname:pfnInternalFree will be called.
An implementation will only call an informational callback for executable
memory allocations and frees.
[open,refpage='VkInternalAllocationType',desc='Allocation type',type='enums',xrefs='PFN_vkInternalAllocationNotification PFN_vkInternalFreeNotification']
--
The pname:allocationType parameter to the pname:pfnInternalAllocation and
pname:pfnInternalFree functions may: be one of the following values:
include::../api/enums/VkInternalAllocationType.txt[]
* ename: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 an
sname:VkAllocationCallbacks structure between the time a ftext:vkCreate*
command returns and the time a corresponding ftext:vkDestroy* command
begins, that implementation must: save a copy of the allocator before the
ftext: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 ftext:vkCreate* command, a _compatible_
allocator must: be provided to the corresponding ftext:vkDestroy* command.
Two sname:VkAllocationCallbacks structures are compatible if memory
allocated with pname:pfnAllocation or pname:pfnReallocation in each can: be
freed with pname:pfnReallocation or pname:pfnFree in the other.
An allocator must: not be provided to a ftext:vkDestroy* command if an
allocator was not provided to the corresponding ftext:vkCreate* command.
If a non-`NULL` allocator is used, the pname:pfnAllocation,
pname:pfnReallocation and pname: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 pname:pfnInternalAllocation and pname:pfnInternalFree to `NULL`.
pname:pfnInternalAllocation and pname:pfnInternalFree must: either both be
`NULL` or both be non-`NULL`.
If pname:pfnAllocation or pname:pfnReallocation fail, the implementation
may: fail object creation and/or generate an
ename: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.
pname:pfnAllocation or pname:pfnReallocation may: be called in the following
situations:
* Allocations scoped to a sname:VkDevice or sname:VkInstance may: be
allocated from any API command.
* Allocations scoped to a command may: be allocated from any API command.
* Allocations scoped to a sname:VkPipelineCache may: only be allocated
from:
** fname:vkCreatePipelineCache
** fname:vkMergePipelineCaches for pname:dstCache
** fname:vkCreateGraphicsPipelines for pname:pipelineCache
** fname:vkCreateComputePipelines for pname:pipelineCache
ifdef::VK_EXT_validation_cache[]
* Allocations scoped to a sname:VkValidationCacheEXT may: only be
allocated from:
** fname:vkCreateValidationCacheEXT
** fname:vkMergeValidationCachesEXT for pname:dstCache
** fname:vkCreateShaderModule for pname:validationCache in
sname:VkShaderModuleValidationCacheCreateInfoEXT
endif::VK_EXT_validation_cache[]
* Allocations scoped to a sname:VkDescriptorPool may: only be allocated
from:
** any command that takes the pool as a direct argument
** fname:vkAllocateDescriptorSets for the pname:descriptorPool member of
its pname:pAllocateInfo parameter
** fname:vkCreateDescriptorPool
* Allocations scoped to a sname:VkCommandPool may: only be allocated from:
** any command that takes the pool as a direct argument
** fname:vkCreateCommandPool
** fname:vkAllocateCommandBuffers for the pname:commandPool member of its
pname:pAllocateInfo parameter
** any ftext:vkCmd* command whose pname:commandBuffer was allocated from
that sname:VkCommandPool
* Allocations scoped to any other object may: only be allocated in that
object's ftext:vkCreate* command.
pname:pfnFree may: be called in the following situations:
* Allocations scoped to a sname:VkDevice or sname:VkInstance 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 sname:VkPipelineCache may: be freed from
fname:vkDestroyPipelineCache.
ifdef::VK_EXT_validation_cache[]
* Allocations scoped to a sname:VkValidationCacheEXT may: be freed from
fname:vkDestroyValidationCacheEXT.
endif::VK_EXT_validation_cache[]
* Allocations scoped to a sname:VkDescriptorPool may: be freed from
** any command that takes the pool as a direct argument
* Allocations scoped to a sname:VkCommandPool may: be freed from:
** any command that takes the pool as a direct argument
** fname:vkResetCommandBuffer whose pname:commandBuffer was allocated from
that sname:VkCommandPool
* Allocations scoped to any other object may: be freed in that object's
ftext:vkDestroy* command.
* Any command that allocates host memory may: also free host memory of the
same scope.
[[memory-device]]
== 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.
Memory properties of a physical device describe the memory heaps and memory
types available.
[open,refpage='vkGetPhysicalDeviceMemoryProperties',desc='Reports memory information for the specified physical device',type='protos']
--
To query memory properties, call:
include::../api/protos/vkGetPhysicalDeviceMemoryProperties.txt[]
* pname:physicalDevice is the handle to the device to query.
* pname:pMemoryProperties points to an instance of
sname:VkPhysicalDeviceMemoryProperties structure in which the properties
are returned.
include::../validity/protos/vkGetPhysicalDeviceMemoryProperties.txt[]
--
[open,refpage='VkPhysicalDeviceMemoryProperties',desc='Structure specifying physical device memory properties',type='structs']
--
The sname:VkPhysicalDeviceMemoryProperties structure is defined as:
include::../api/structs/VkPhysicalDeviceMemoryProperties.txt[]
* pname:memoryTypeCount is the number of valid elements in the
pname:memoryTypes array.
* pname:memoryTypes is an array of slink:VkMemoryType structures
describing the _memory types_ that can: be used to access memory
allocated from the heaps specified by pname:memoryHeaps.
* pname:memoryHeapCount is the number of valid elements in the
pname:memoryHeaps array.
* pname:memoryHeaps is an array of slink:VkMemoryHeap structures
describing the _memory heaps_ from which memory can: be allocated.
The sname: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 pname:memoryHeapCount and is less
than or equal to ename:VK_MAX_MEMORY_HEAPS.
Each heap is described by an element of the pname:memoryHeaps array as a
slink:VkMemoryHeap structure.
The number of memory types available across all memory heaps is given by
pname:memoryTypeCount and is less than or equal to
ename:VK_MAX_MEMORY_TYPES.
Each memory type is described by an element of the pname:memoryTypes array
as a slink:VkMemoryType structure.
At least one heap must: include ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT in
slink:VkMemoryHeap::pname:flags.
If there are multiple heaps that all have similar performance
characteristics, they may: all include
ename: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.
[[memory-device-bitmask-list]]
Each memory type returned by flink:vkGetPhysicalDeviceMemoryProperties must:
have its pname:propertyFlags set to one of the following values:
* 0
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT | +
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | +
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
There must: be at least one memory type with both the
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bits set in its
pname:propertyFlags.
There must: be at least one memory type with the
ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit set in its
pname:propertyFlags.
For each pair of elements *X* and *Y* returned in pname:memoryTypes, *X*
must: be placed at a lower index position than *Y* if:
* either the set of bit flags returned in the pname:propertyFlags member
of *X* is a strict subset of the set of bit flags returned in the
pname:propertyFlags member of *Y*.
* or the pname: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).
[NOTE]
.Note
====
There is no ordering requirement between *X* and *Y* elements for the case
their pname:propertyFlags members are not in a subset relation.
That potentially allows more than one possible way to order the same set of
memory types.
Notice that the <<memory-device-bitmask-list,list of all allowed memory
property flag combinations>> is written in the required order.
But if instead ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT was before
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, the list would still be in the
required order.
====
This ordering requirement enables applications to use a simple search loop
to select the desired memory type along the lines of:
[source,c++]
---------------------------------------------------
// 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);
---------------------------------------------------
include::../validity/structs/VkPhysicalDeviceMemoryProperties.txt[]
--
ifdef::VK_KHR_get_physical_device_properties2[]
[open,refpage='vkGetPhysicalDeviceMemoryProperties2KHR',desc='Reports memory information for the specified physical device',type='protos']
--
To query memory properties, call:
include::../api/protos/vkGetPhysicalDeviceMemoryProperties2KHR.txt[]
* pname:physicalDevice is the handle to the device to query.
* pname:pMemoryProperties points to an instance of
sname:VkPhysicalDeviceMemoryProperties2KHR structure in which the
properties are returned.
fname:vkGetPhysicalDeviceMemoryProperties2KHR behaves similarly to
flink:vkGetPhysicalDeviceMemoryProperties, with the ability to return
extended information in a pname:pNext chain of output structures.
include::../validity/protos/vkGetPhysicalDeviceMemoryProperties2KHR.txt[]
--
[open,refpage='VkPhysicalDeviceMemoryProperties2KHR',desc='Structure specifying physical device memory properties',type='structs']
--
The sname:VkPhysicalDeviceMemoryProperties2KHR structure is defined as:
include::../api/structs/VkPhysicalDeviceMemoryProperties2KHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:memoryProperties is a structure of type
slink:VkPhysicalDeviceMemoryProperties which is populated with the same
values as in flink:vkGetPhysicalDeviceMemoryProperties.
include::../validity/structs/VkPhysicalDeviceMemoryProperties2KHR.txt[]
--
endif::VK_KHR_get_physical_device_properties2[]
[open,refpage='VkMemoryHeap',desc='Structure specifying a memory heap',type='structs']
--
The sname:VkMemoryHeap structure is defined as:
include::../api/structs/VkMemoryHeap.txt[]
* pname:size is the total memory size in bytes in the heap.
* pname:flags is a bitmask of elink:VkMemoryHeapFlagBits specifying
attribute flags for the heap.
include::../validity/structs/VkMemoryHeap.txt[]
--
[open,refpage='VkMemoryHeapFlagBits',desc='Bitmask specifying attribute flags for a heap',type='enums']
--
Bits which may: be set in slink:VkMemoryHeap::pname:flags, indicating
attribute flags for the heap, are:
include::../api/enums/VkMemoryHeapFlagBits.txt[]
* ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT indicates 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.
ifdef::VK_KHX_device_group_creation[]
* ename:VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHX indicates 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.
endif::VK_KHX_device_group_creation[]
--
[open,refpage='VkMemoryType',desc='Structure specifying memory type',type='structs']
--
The sname:VkMemoryType structure is defined as:
include::../api/structs/VkMemoryType.txt[]
* pname:heapIndex describes which memory heap this memory type corresponds
to, and must: be less than pname:memoryHeapCount from the
slink:VkPhysicalDeviceMemoryProperties structure.
* pname:propertyFlags is a bitmask of elink:VkMemoryPropertyFlagBits of
properties for this memory type.
include::../validity/structs/VkMemoryType.txt[]
--
[open,refpage='VkMemoryPropertyFlagBits',desc='Bitmask specifying properties for a memory type',type='enums']
--
Bits which may: be set in slink:VkMemoryType::pname:propertyFlags,
indicating properties of a memory heap, are:
include::../api/enums/VkMemoryPropertyFlagBits.txt[]
* ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit indicates 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 the ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT set.
* ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit indicates that memory
allocated with this type can: be mapped for host access using
flink:vkMapMemory.
* ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit indicates that the host
cache management commands flink:vkFlushMappedMemoryRanges and
flink:vkInvalidateMappedMemoryRanges are not needed to flush host writes
to the device or make device writes visible to the host, respectively.
* ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT bit indicates 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.
* ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit indicates that the
memory type only allows device access to the memory.
Memory types must: not have both
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT and
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set.
Additionally, the object's backing memory may: be provided by the
implementation lazily as specified in <<memory-device-lazy_allocation,
Lazily Allocated Memory>>.
--
[open,refpage='VkDeviceMemory',desc='Opaque handle to a device memory object',type='handles']
--
A Vulkan device operates on data in device memory via memory objects that
are represented in the API by a sname:VkDeviceMemory handle:
include::../api/handles/VkDeviceMemory.txt[]
--
[open,refpage='vkAllocateMemory',desc='Allocate GPU memory',type='protos']
--
To allocate memory objects, call:
include::../api/protos/vkAllocateMemory.txt[]
* pname:device is the logical device that owns the memory.
* pname:pAllocateInfo is a pointer to an instance of the
slink:VkMemoryAllocateInfo structure describing parameters of the
allocation.
A successful returned allocation must: use the requested parameters --
no substitution is permitted by the implementation.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, Memory Allocation>> chapter.
* pname:pMemory is a pointer to a sname:VkDeviceMemory handle in which
information about the allocated memory is returned.
Allocations returned by fname: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.
The maximum number of valid memory allocations that can: exist
simultaneously within a slink:VkDevice may: be restricted by implementation-
or platform-dependent limits.
If a call to flink:vkAllocateMemory would cause the total number of
allocations to exceed these limits, such a call will fail and must: return
ename:VK_ERROR_TOO_MANY_OBJECTS.
The
<<features-limits-maxMemoryAllocationCount,pname:maxMemoryAllocationCount>>
feature describes the number of allocations that can: exist simultaneously
before encountering these internal limits.
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 ename:VK_ERROR_OUT_OF_DEVICE_MEMORY must: be returned.
.Valid Usage
****
* [[VUID-vkAllocateMemory-pAllocateInfo-01713]]
pname:pAllocateInfo\->pname:allocationSize must: be less than or equal
to
slink:VkPhysicalDeviceMemoryProperties::pname:memoryHeaps[pname:pAllocateInfo\->pname:memoryTypeIndex].pname:size
as returned by flink:vkGetPhysicalDeviceMemoryProperties for the
slink:VkPhysicalDevice that pname:device was created from.
* [[VUID-vkAllocateMemory-pAllocateInfo-01714]]
pname:pAllocateInfo\->pname:memoryTypeIndex must: be less than
slink:VkPhysicalDeviceMemoryProperties::pname:memoryTypeCount as
returned by flink:vkGetPhysicalDeviceMemoryProperties for the
slink:VkPhysicalDevice that pname:device was created from.
****
include::../validity/protos/vkAllocateMemory.txt[]
--
[open,refpage='VkMemoryAllocateInfo',desc='Structure containing parameters of a memory allocation',type='structs']
--
The sname:VkMemoryAllocateInfo structure is defined as:
include::../api/structs/VkMemoryAllocateInfo.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:allocationSize is the size of the allocation in bytes
* pname:memoryTypeIndex is an index identifying a memory type from the
pname:memoryTypes array of the slink:VkPhysicalDeviceMemoryProperties
structure
ifdef::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd,VK_EXT_external_memory_host[]
An instance of the slink:VkMemoryAllocateInfo structure defines a memory
import operation if the pname:pNext chain contains an instance of one of the
following structures with a non-zero value for their respective
pname:handleType member:
ifdef::VK_KHR_external_memory_win32[]
* slink:VkImportMemoryWin32HandleInfoKHR
endif::VK_KHR_external_memory_win32[]
ifdef::VK_KHR_external_memory_fd[]
* slink:VkImportMemoryFdInfoKHR
endif::VK_KHR_external_memory_fd[]
ifdef::VK_EXT_external_memory_host[]
* slink:VkImportMemoryHostPointerInfoEXT
endif::VK_EXT_external_memory_host[]
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]
.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.
====
When performing a memory import operation, it is the responsibility of the
application to ensure the external handles meet all valid usage
requirements.
However, implementations must: perform sufficient validation of external
handles 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
ename:VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR.
endif::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd,VK_EXT_external_memory_host[]
.Valid Usage
****
* [[VUID-VkMemoryAllocateInfo-allocationSize-00638]]
pname:allocationSize must: be greater than `0`
ifdef::VK_KHR_external_memory[]
ifdef::VK_KHR_dedicated_allocation,VK_NV_dedicated_allocation[]
* [[VUID-VkMemoryAllocateInfo-pNext-00639]]
If the pname:pNext chain contains an instance of
sname:VkExportMemoryAllocateInfoKHR, and any of the handle types
specified in sname:VkExportMemoryAllocateInfoKHR::pname:handleTypes
require a dedicated allocation, as reported by
flink:vkGetPhysicalDeviceImageFormatProperties2KHR in
sname:VkExternalImageFormatPropertiesKHR::pname:externalMemoryProperties::pname:externalMemoryFeatures
or
sname:VkExternalBufferPropertiesKHR::pname:externalMemoryProperties::pname:externalMemoryFeatures,
the pname:pNext chain must contain an instance of
ifdef::VK_KHR_dedicated_allocation[slink:VkMemoryDedicatedAllocateInfoKHR]
ifdef::VK_KHR_dedicated_allocation+VK_NV_dedicated_allocation[or]
ifdef::VK_NV_dedicated_allocation[slink:VkDedicatedAllocationMemoryAllocateInfoNV]
with either its pname:image or pname:buffer field set to a value other
than ename:VK_NULL_HANDLE.
endif::VK_KHR_dedicated_allocation,VK_NV_dedicated_allocation[]
endif::VK_KHR_external_memory[]
ifdef::VK_KHR_external_memory+VK_NV_external_memory[]
* [[VUID-VkMemoryAllocateInfo-pNext-00640]]
If the pname:pNext chain contains an instance of
slink:VkExportMemoryAllocateInfoKHR, it must: not contain an instance of
slink:VkExportMemoryAllocateInfoNV or
slink:VkExportMemoryWin32HandleInfoNV.
endif::VK_KHR_external_memory+VK_NV_external_memory[]
ifdef::VK_KHR_external_memory_win32+VK_NV_external_memory_win32[]
* [[VUID-VkMemoryAllocateInfo-pNext-00641]]
If the pname:pNext chain contains an instance of
slink:VkImportMemoryWin32HandleInfoKHR, it must: not contain an instance
of slink:VkImportMemoryWin32HandleInfoNV.
endif::VK_KHR_external_memory_win32+VK_NV_external_memory_win32[]
ifdef::VK_KHR_external_memory_fd[]
* [[VUID-VkMemoryAllocateInfo-allocationSize-01742]]
If the parameters define an import operation, the external handle
specified was created by the Vulkan API, and the external handle type is
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR, then the values
of pname:allocationSize and pname:memoryTypeIndex must: match those
specified when the memory object being imported was created.
endif::VK_KHR_external_memory_fd[]
ifdef::VK_KHR_external_memory+VK_KHX_device_group[]
* [[VUID-VkMemoryAllocateInfo-None-00643]]
If the parameters define an import operation and the external handle
specified was created by the Vulkan API, the device mask specified by
slink:VkMemoryAllocateFlagsInfoKHX must: match that specified when the
memory object being imported was allocated.
* [[VUID-VkMemoryAllocateInfo-None-00644]]
If the parameters define an import operation and the external handle
specified was created by the Vulkan API, the list of physical devices
that comprise the logical device passed to flink:vkAllocateMemory must:
match the list of physical devices that comprise the logical device on
which the memory was originally allocated.
endif::VK_KHR_external_memory+VK_KHX_device_group[]
ifdef::VK_KHR_external_memory_win32[]
* [[VUID-VkMemoryAllocateInfo-memoryTypeIndex-00645]]
If the parameters define an import operation and the external handle is
an NT handle or a global share handle created outside of the Vulkan API,
the value of pname:memoryTypeIndex must: be one of those returned by
flink:vkGetMemoryWin32HandlePropertiesKHR.
* [[VUID-VkMemoryAllocateInfo-allocationSize-01743]]
If the parameters define an import operation, the external handle was
created by the Vulkan API, and the external handle type is
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR or
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR, then the
values of pname:allocationSize and pname:memoryTypeIndex must: match
those specified when the memory object being imported was created.
* [[VUID-VkMemoryAllocateInfo-allocationSize-00646]]
If the parameters define an import operation and the external handle
type is ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR,
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR, or
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR,
pname:allocationSize must: match the size reported in the memory
requirements of the pname:image or pname:buffer member of the instance
of sname:VkDedicatedAllocationMemoryAllocateInfoNV included in the
pname:pNext chain.
* [[VUID-VkMemoryAllocateInfo-allocationSize-00647]]
If the parameters define an import operation and the external handle
type is ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR,
pname:allocationSize must: match the size specified when creating the
Direct3D 12 heap from which the external handle was extracted.
endif::VK_KHR_external_memory_win32[]
ifdef::VK_KHR_external_memory_fd[]
* [[VUID-VkMemoryAllocateInfo-memoryTypeIndex-00648]]
If the parameters define an import operation and the external handle is
a POSIX file descriptor created outside of the Vulkan API, the value of
pname:memoryTypeIndex must: be one of those returned by
flink:vkGetMemoryFdPropertiesKHR.
endif::VK_KHR_external_memory_fd[]
ifdef::VK_EXT_external_memory_host[]
* [[VUID-VkMemoryAllocateInfo-memoryTypeIndex-01744]]
If the parameters define an import operation and the external handle is
a host pointer, the value of pname:memoryTypeIndex must: be one of those
returned by flink:vkGetMemoryHostPointerPropertiesEXT
* [[VUID-VkMemoryAllocateInfo-allocationSize-01745]]
If the parameters define an import operation and the external handle is
a host pointer, pname:allocationSize must: be an integer multiple of
sname:VkPhysicalDeviceExternalMemoryHostPropertiesEXT::pname:minImportedHostPointerAlignment
endif::VK_EXT_external_memory_host[]
****
include::../validity/structs/VkMemoryAllocateInfo.txt[]
--
ifdef::VK_KHR_dedicated_allocation[]
[open,refpage='VkMemoryDedicatedAllocateInfoKHR',desc='Specify a dedicated memory allocation resource',type='structs']
--
If the pname:pNext chain includes a sname:VkMemoryDedicatedAllocateInfoKHR
structure, then that structure includes a handle of the sole buffer or image
resource that the memory can: be bound to.
The sname:VkMemoryDedicatedAllocateInfoKHR structure is defined as:
include::../api/structs/VkMemoryDedicatedAllocateInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:image is dlink:VK_NULL_HANDLE or a handle of an image which this
memory will be bound to.
* pname:buffer is dlink:VK_NULL_HANDLE or a handle of a buffer which this
memory will be bound to.
.Valid Usage
****
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01432]]
At least one of pname:image and pname:buffer must: be
dlink:VK_NULL_HANDLE
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01433]]
If pname:image is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the image
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01434]]
If pname:image is not dlink:VK_NULL_HANDLE, pname:image must: have been
created without ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT set in
slink:VkImageCreateInfo::pname:flags
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-buffer-01435]]
If pname:buffer is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the buffer
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-buffer-01436]]
If pname:buffer is not dlink:VK_NULL_HANDLE, pname:buffer must: have
been created without ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT set in
slink:VkBufferCreateInfo::pname:flags
ifdef::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-image-01437]]
If pname:image is not dlink:VK_NULL_HANDLE and
slink:VkMemoryAllocateInfo defines a memory import operation, the memory
being imported must: also be a dedicated image allocation and
pname:image must be identical to the image associated with the imported
memory.
* [[VUID-VkMemoryDedicatedAllocateInfoKHR-buffer-01438]]
If pname:buffer is not dlink:VK_NULL_HANDLE and
slink:VkMemoryAllocateInfo defines a memory import operation, the memory
being imported must: also be a dedicated buffer allocation and
pname:buffer must be identical to the buffer associated with the
imported memory.
endif::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
****
include::../validity/structs/VkMemoryDedicatedAllocateInfoKHR.txt[]
--
endif::VK_KHR_dedicated_allocation[]
ifdef::VK_NV_dedicated_allocation[]
[open,refpage='VkDedicatedAllocationMemoryAllocateInfoNV',desc='Specify a dedicated memory allocation resource',type='structs']
--
If the pname:pNext chain includes a
sname:VkDedicatedAllocationMemoryAllocateInfoNV structure, then that
structure includes a handle of the sole buffer or image resource that the
memory can: be bound to.
The sname:VkDedicatedAllocationMemoryAllocateInfoNV structure is defined as:
include::../api/structs/VkDedicatedAllocationMemoryAllocateInfoNV.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:image is dlink:VK_NULL_HANDLE or a handle of an image which this
memory will be bound to.
* pname:buffer is dlink:VK_NULL_HANDLE or a handle of a buffer which this
memory will be bound to.
.Valid Usage
****
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00649]]
At least one of pname:image and pname:buffer must: be
dlink:VK_NULL_HANDLE
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00650]]
If pname:image is not dlink:VK_NULL_HANDLE, the image must: have been
created with
sname:VkDedicatedAllocationImageCreateInfoNV::pname:dedicatedAllocation
equal to ename:VK_TRUE
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-buffer-00651]]
If pname:buffer is not dlink:VK_NULL_HANDLE, the buffer must: have been
created with
sname:VkDedicatedAllocationBufferCreateInfoNV::pname:dedicatedAllocation
equal to ename:VK_TRUE
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00652]]
If pname:image is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the image
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-buffer-00653]]
If pname:buffer is not dlink:VK_NULL_HANDLE,
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
sname:VkMemoryRequirements::pname:size of the buffer
ifdef::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00654]]
If pname:image is not dlink:VK_NULL_HANDLE and
slink:VkMemoryAllocateInfo defines a memory import operation, the memory
being imported must: also be a dedicated image allocation and
pname:image must: be identical to the image associated with the imported
memory.
* [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-buffer-00655]]
If pname:buffer is not dlink:VK_NULL_HANDLE and
slink:VkMemoryAllocateInfo defines a memory import operation, the memory
being imported must: also be a dedicated buffer allocation and
pname:buffer must: be identical to the buffer associated with the
imported memory.
endif::VK_KHR_external_memory_win32,VK_KHR_external_memory_fd[]
****
include::../validity/structs/VkDedicatedAllocationMemoryAllocateInfoNV.txt[]
--
endif::VK_NV_dedicated_allocation[]
ifdef::VK_KHR_external_memory[]
[open,refpage='VkExportMemoryAllocateInfoKHR',desc='Specify exportable handle types for a device memory object',type='structs']
--
When allocating memory that may: be exported to another process or Vulkan
instance, add a slink:VkExportMemoryAllocateInfoKHR structure to the
pname:pNext chain of the slink:VkMemoryAllocateInfo structure, specifying
the handle types that may: be exported.
The slink:VkExportMemoryAllocateInfoKHR structure is defined as:
include::../api/structs/VkExportMemoryAllocateInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:handleTypes is a bitmask of
elink:VkExternalMemoryHandleTypeFlagBitsKHR 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.
.Valid Usage
****
* [[VUID-VkExportMemoryAllocateInfoKHR-handleTypes-00656]]
The bits in pname:handleTypes must: be supported and compatible, as
reported by slink:VkExternalImageFormatPropertiesKHR or
slink:VkExternalBufferPropertiesKHR.
****
include::../validity/structs/VkExportMemoryAllocateInfoKHR.txt[]
--
endif::VK_KHR_external_memory[]
ifdef::VK_KHR_external_memory_win32[]
[open,refpage='VkExportMemoryWin32HandleInfoKHR',desc='Structure specifying additional attributes of Windows handles exported from a memory',type='structs']
--
To specify additional attributes of NT handles exported from a memory
object, add the slink:VkExportMemoryWin32HandleInfoKHR structure to the
pname:pNext chain of the slink:VkMemoryAllocateInfo structure.
The sname:VkExportMemoryWin32HandleInfoKHR structure is defined as:
include::../api/structs/VkExportMemoryWin32HandleInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:pAttributes is a pointer to a Windows code:SECURITY_ATTRIBUTES
structure specifying security attributes of the handle.
* pname:dwAccess is a code:DWORD specifying access rights of the handle.
* pname:name is a NULL-terminated UTF-16 string to associate with the
underlying resource referenced by NT handles exported from the created
memory.
If this structure is not present, or if pname: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
code:DXGI_SHARED_RESOURCE_READ | code:DXGI_SHARED_RESOURCE_WRITE
for handles of the following types:
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR
And
code:GENERIC_ALL
for handles of the following types:
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR
1::
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686670.aspx
.Valid Usage
****
* [[VUID-VkExportMemoryWin32HandleInfoKHR-handleTypes-00657]]
If slink:VkExportMemoryAllocateInfoKHR::pname:handleTypes does not
include ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR,
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR,
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR, or
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR,
VkExportMemoryWin32HandleInfoKHR must: not be in the pname:pNext chain
of slink:VkMemoryAllocateInfo.
****
include::../validity/structs/VkExportMemoryWin32HandleInfoKHR.txt[]
--
[open,refpage='VkImportMemoryWin32HandleInfoKHR',desc='import Win32 memory created on the same physical device',type='structs']
--
To import memory from a Windows handle, add a
slink:VkImportMemoryWin32HandleInfoKHR structure to the pname:pNext chain of
the slink:VkMemoryAllocateInfo structure.
The sname:VkImportMemoryWin32HandleInfoKHR structure is defined as:
include::../api/structs/VkImportMemoryWin32HandleInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:handleType specifies the type of pname:handle or pname:name.
* pname:handle is the external handle to import, or `NULL`.
* pname:name is a NULL-terminated UTF-16 string naming the underlying
memory resource to import, or `NULL`.
Importing memory objects 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
ownership using the code:CloseHandle system call when the handle is no
longer needed.
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
sname:VkDeviceMemory object.
.Valid Usage
****
* [[VUID-VkImportMemoryWin32HandleInfoKHR-handleType-00658]]
If pname:handleType is not `0`, it must: be supported for import, as
reported by slink:VkExternalImageFormatPropertiesKHR or
slink:VkExternalBufferPropertiesKHR.
* [[VUID-VkImportMemoryWin32HandleInfoKHR-handle-00659]]
The memory from which pname:handle was exported, or the memory named by
pname:name must: have been created on the same underlying physical
device as pname:device.
* [[VUID-VkImportMemoryWin32HandleInfoKHR-handleType-00660]]
If pname:handleType is not `0`, it must: be defined as an NT handle or a
global share handle.
* [[VUID-VkImportMemoryWin32HandleInfoKHR-handleType-01439]]
If pname:handleType is not
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR,
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR,
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR, or
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR, pname:name
must: be `NULL`.
* [[VUID-VkImportMemoryWin32HandleInfoKHR-handleType-01440]]
If pname:handleType is not `0` and pname:handle is `NULL`, pname:name
must: name a valid memory resource of the type specified by
pname:handleType.
* [[VUID-VkImportMemoryWin32HandleInfoKHR-handleType-00661]]
If pname:handleType is not `0` and pname:name is `NULL`, pname:handle
must: be a valid handle of the type specified by pname:handleType.
* [[VUID-VkImportMemoryWin32HandleInfoKHR-handle-01441]]
if pname:handle is not `NULL`, pname:name must be `NULL`.
* [[VUID-VkImportMemoryWin32HandleInfoKHR-handle-01518]]
If pname:handle is not `NULL`, it must: obey any requirements listed for
pname:handleType in
<<external-memory-handle-types-compatibility,external memory handle
types compatibility>>.
* [[VUID-VkImportMemoryWin32HandleInfoKHR-name-01519]]
If pname:name is not `NULL`, it must: obey any requirements listed for
pname:handleType in
<<external-memory-handle-types-compatibility,external memory handle
types compatibility>>.
****
include::../validity/structs/VkImportMemoryWin32HandleInfoKHR.txt[]
--
[open,refpage='vkGetMemoryWin32HandleKHR',desc='Get a Windows HANDLE for a memory object',type='protos']
--
To export a Windows handle representing the underlying resources of a Vulkan
device memory object, call:
include::../api/protos/vkGetMemoryWin32HandleKHR.txt[]
* pname:device is the logical device that created the device memory being
exported.
* pname:pGetWin32HandleInfo is a pointer to an instance of the
slink:VkMemoryGetWin32HandleInfoKHR structure containing parameters of
the export operation.
* pname:pHandle will return the Windows handle representing the underlying
resources of the device memory object.
For handle types defined as NT handles, the handles returned by
fname:vkGetMemoryWin32HandleKHR are owned by the application.
To avoid leaking resources, the application must: release ownership of them
using the code:CloseHandle system call when they are no longer needed.
include::../validity/protos/vkGetMemoryWin32HandleKHR.txt[]
--
[open,refpage='VkMemoryGetWin32HandleInfoKHR',desc='Structure describing a Win32 handle semaphore export operation',type='structs']
--
The sname:VkMemoryGetWin32HandleInfoKHR structure is defined as:
include::../api/structs/VkMemoryGetWin32HandleInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:memory is the memory object from which the handle will be
exported.
* pname:handleType is the type of handle requested.
The properties of the handle returned depend on the value of
pname:handleType.
See elink:VkExternalMemoryHandleTypeFlagBitsKHR for a description of the
properties of the defined external memory handle types.
.Valid Usage
****
* [[VUID-vkGetMemoryWin32HandleKHR-handleType-00662]]
pname:handleType must: have been included in
slink:VkExportMemoryAllocateInfoKHR::pname:handleTypes when pname:memory
was created.
* [[VUID-vkGetMemoryWin32HandleKHR-handleType-00663]]
If pname:handleType is defined as an NT handle,
flink:vkGetMemoryWin32HandleKHR must: be called no more than once for
each valid unique combination of pname:memory and pname:handleType.
* [[VUID-vkGetMemoryWin32HandleKHR-handleType-00664]]
pname:handleType must: be defined as an NT handle or a global share
handle.
****
include::../validity/structs/VkMemoryGetWin32HandleInfoKHR.txt[]
--
[open,refpage='vkGetMemoryWin32HandlePropertiesKHR',desc='Get Properties of External Memory Win32 Handles',type='protos']
--
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:
include::../api/protos/vkGetMemoryWin32HandlePropertiesKHR.txt[]
* pname:device is the logical device that will be importing pname:handle.
* pname:handleType is the type of the handle pname:handle.
* pname:handle is the handle which will be imported.
* pname:pMemoryWin32HandleProperties will return properties of
pname:handle.
.Valid Usage
****
* [[VUID-vkGetMemoryWin32HandlePropertiesKHR-handle-00665]]
pname:handle must: be an external memory handle created outside of the
Vulkan API.
* [[VUID-vkGetMemoryWin32HandlePropertiesKHR-handleType-00666]]
pname:handleType must: not be one of the handle types defined as opaque.
****
include::../validity/protos/vkGetMemoryWin32HandlePropertiesKHR.txt[]
--
[open,refpage='VkMemoryWin32HandlePropertiesKHR',desc='Properties of External Memory Windows Handles',type='structs']
--
The sname:VkMemoryWin32HandlePropertiesKHR structure returned is defined as:
include::../api/structs/VkMemoryWin32HandlePropertiesKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:memoryTypeBits is a bitmask containing one bit set for every
memory type which the specified windows handle can: be imported as.
--
endif::VK_KHR_external_memory_win32[]
ifdef::VK_KHR_external_memory_fd[]
[open,refpage='VkImportMemoryFdInfoKHR',desc='import memory created on the same physical device from a file descriptor',type='structs']
--
To import memory from a POSIX file descriptor handle, add a
slink:VkImportMemoryFdInfoKHR structure to the pname:pNext chain of the
slink:VkMemoryAllocateInfo structure.
The sname:VkImportMemoryFdInfoKHR structure is defined as:
include::../api/structs/VkImportMemoryFdInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:handleType specifies the handle type of pname:fd.
* pname: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.
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
sname:VkDeviceMemory object.
.Valid Usage
****
* [[VUID-VkImportMemoryFdInfoKHR-handleType-00667]]
If pname:handleType is not `0`, it must: be supported for import, as
reported by slink:VkExternalImageFormatPropertiesKHR or
slink:VkExternalBufferPropertiesKHR.
* [[VUID-VkImportMemoryFdInfoKHR-handleType-00669]]
If pname:handleType is not `0`, it must: be defined as a POSIX file
descriptor handle.
* [[VUID-VkImportMemoryFdInfoKHR-handleType-00670]]
If pname:handleType is not `0`, pname:fd must: be a valid handle of the
type specified by pname:handleType.
* [[VUID-VkImportMemoryFdInfoKHR-fd-01746]]
The memory represented by pname:fd must: have been created from a
physical device and driver that is compatible with pname:device and
pname:handleType, as described in
<<external-memory-handle-types-compatibility>>.
* [[VUID-VkImportMemoryFdInfoKHR-fd-01520]]
pname:fd must: obey any requirements listed for pname:handleType in
<<external-memory-handle-types-compatibility,external memory handle
types compatibility>>.
****
include::../validity/structs/VkImportMemoryFdInfoKHR.txt[]
--
[open,refpage='vkGetMemoryFdKHR',desc='Get a POSIX file descriptor for a memory object',type='protos']
--
To export a POSIX file descriptor representing the underlying resources of a
Vulkan device memory object, call:
include::../api/protos/vkGetMemoryFdKHR.txt[]
* pname:device is the logical device that created the device memory being
exported.
* pname:pGetFdInfo is a pointer to an instance of the
slink:VkMemoryGetFdInfoKHR structure containing parameters of the export
operation.
* pname:pFd will return a file descriptor representing the underlying
resources of the device memory object.
Each call to fname:vkGetMemoryFdKHR must: create a new file descriptor and
transfer ownership of it to the application.
To avoid leaking resources, the application must: release ownership of the
file descriptor using the code: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 code:execve system call
is made.
include::../validity/protos/vkGetMemoryFdKHR.txt[]
--
[open,refpage='VkMemoryGetFdInfoKHR',desc='Structure describing a POSIX FD semaphore export operation',type='structs']
--
The sname:VkMemoryGetFdInfoKHR structure is defined as:
include::../api/structs/VkMemoryGetFdInfoKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:memory is the memory object from which the handle will be
exported.
* pname:handleType is the type of handle requested.
The properties of the file descriptor exported depend on the value of
pname:handleType.
See elink:VkExternalMemoryHandleTypeFlagBitsKHR for a description of the
properties of the defined external memory handle types.
ifdef::VK_EXT_external_memory_dma_buf[]
[NOTE]
.Note
====
The size of the exported file may: be larger than the size requested by
slink:VkMemoryAllocateInfo::allocationSize.
If pname:handleType is ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
then the application can: query the file's actual size with
link:man:lseek(2)[lseek(2)].
====
endif::VK_EXT_external_memory_dma_buf[]
.Valid Usage
****
* [[VUID-vkGetMemoryFdKHR-handleType-00671]]
pname:handleType must: have been included in
slink:VkExportMemoryAllocateInfoKHR::pname:handleTypes when pname:memory
was created.
* [[VUID-vkGetMemoryFdKHR-handleType-00672]]
pname:handleType must: be defined as a POSIX file descriptor handle.
****
include::../validity/structs/VkMemoryGetFdInfoKHR.txt[]
--
[open,refpage='vkGetMemoryFdPropertiesKHR',desc='Get Properties of External Memory File Descriptors',type='protos']
--
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:
include::../api/protos/vkGetMemoryFdPropertiesKHR.txt[]
* pname:device is the logical device that will be importing pname:fd.
* pname:handleType is the type of the handle pname:fd.
* pname:fd is the handle which will be imported.
* pname:pMemoryFdProperties will return properties of the handle pname:fd.
.Valid Usage
****
* [[VUID-vkGetMemoryFdPropertiesKHR-fd-00673]]
pname:fd must: be an external memory handle created outside of the
Vulkan API.
* [[VUID-vkGetMemoryFdPropertiesKHR-handleType-00674]]
pname:handleType must: not be
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR.
****
include::../validity/protos/vkGetMemoryFdPropertiesKHR.txt[]
--
[open,refpage='VkMemoryFdPropertiesKHR',desc='Properties of External Memory File Descriptors',type='structs']
--
The sname:VkMemoryFdPropertiesKHR structure returned is defined as:
include::../api/structs/VkMemoryFdPropertiesKHR.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:memoryTypeBits is a bitmask containing one bit set for every
memory type which the specified file descriptor can: be imported as.
--
endif::VK_KHR_external_memory_fd[]
ifdef::VK_EXT_external_memory_host[]
[open,refpage='VkImportMemoryHostPointerInfoEXT',desc='import memory from a host pointer',type='structs']
--
To import memory from a host pointer, add a
slink:VkImportMemoryHostPointerInfoEXT structure to the pname:pNext chain of
the slink:VkMemoryAllocateInfo structure.
The sname:VkImportMemoryHostPointerInfoEXT structure is defined as:
include::../api/structs/VkImportMemoryHostPointerInfoEXT.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:handleType specifies the handle type.
* pname: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 underlying memory as defined in
<<memory-device-hostaccess,Host Access to Device Memory Objects>>.
Applications can: import the same underlying memory into multiple instances
of Vulkan and multiple times into a given Vulkan instance.
However, implementations may: fail to import the same underlying memory
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 ename:VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR.
The application must: ensure that the imported memory range remains valid
and accessible for the lifetime of the imported memory object.
.Valid Usage
****
* [[VUID-VkImportMemoryHostPointerInfoEXT-handleType-01747]]
If pname:handleType is not `0`, it must: be supported for import, as
reported in slink:VkExternalMemoryPropertiesKHR
* [[VUID-VkImportMemoryHostPointerInfoEXT-handleType-01748]]
If pname:handleType is not `0`, it must: be
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT or
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT
* [[VUID-VkImportMemoryHostPointerInfoEXT-pHostPointer-01749]]
pname:pHostPointer must: be a pointer aligned to an integer multiple of
sname:VkPhysicalDeviceExternalMemoryHostPropertiesEXT::pname:minImportedHostPointerAlignment
* [[VUID-VkImportMemoryHostPointerInfoEXT-handleType-01750]]
If pname:handleType is
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
pname:pHostPointer must: be a pointer to pname:allocationSize number of
bytes of host memory, where pname:allocationSize is the member of the
sname:VkMemoryAllocateInfo structure this structure is chained to
* [[VUID-VkImportMemoryHostPointerInfoEXT-handleType-01751]]
If pname:handleType is
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT,
pname:pHostPointer must: be a pointer to pname:allocationSize number of
bytes of host mapped foreign memory, where pname:allocationSize is the
member of the sname:VkMemoryAllocateInfo structure this structure is
chained to
****
include::../validity/structs/VkImportMemoryHostPointerInfoEXT.txt[]
--
[open,refpage='vkGetMemoryHostPointerPropertiesEXT',desc='Get properties of external memory host pointer',type='protos']
--
To determine the correct parameters to use when importing host pointers,
call:
include::../api/protos/vkGetMemoryHostPointerPropertiesEXT.txt[]
* pname:device is the logical device that will be importing
pname:pHostPointer.
* pname:handleType is the type of the handle pname:pHostPointer.
* pname:pHostPointer is the host pointer to import from.
.Valid Usage
****
* [[VUID-vkGetMemoryHostPointerPropertiesEXT-handleType-01752]]
pname:handleType must: be
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT or
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT
* [[VUID-vkGetMemoryHostPointerPropertiesEXT-pHostPointer-01753]]
pname:pHostPointer must: be a pointer aligned to an integer multiple of
sname:VkPhysicalDeviceExternalMemoryHostPropertiesEXT::pname:minImportedHostPointerAlignment
* [[VUID-vkGetMemoryHostPointerPropertiesEXT-handleType-01754]]
If pname:handleType is
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
pname:pHostPointer must: be a pointer to host memory
* [[VUID-vkGetMemoryHostPointerPropertiesEXT-handleType-01755]]
If pname:handleType is
ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT,
pname:pHostPointer must: be a pointer to host mapped foreign memory
****
include::../validity/protos/vkGetMemoryHostPointerPropertiesEXT.txt[]
--
[open,refpage='VkMemoryHostPointerPropertiesEXT',desc'Properties of external memory host pointer',type='structs']
--
The sname:VkMemoryHostPointerPropertiesEXT structure is defined as:
include::../api/structs/VkMemoryHostPointerPropertiesEXT.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:memoryTypeBits is a bitmask containing one bit set for every
memory type which the specified host pointer can: be imported as.
include::../validity/structs/VkMemoryHostPointerPropertiesEXT.txt[]
--
endif::VK_EXT_external_memory_host[]
ifdef::VK_NV_external_memory[]
include::VK_NV_external_memory/allocate_memory.txt[]
endif::VK_NV_external_memory[]
ifdef::VK_NV_external_memory_win32[]
include::VK_NV_external_memory_win32/handle_permissions.txt[]
include::VK_NV_external_memory_win32/import_memory_win32.txt[]
include::VK_NV_external_memory_win32/get_handle_win32.txt[]
endif::VK_NV_external_memory_win32[]
ifdef::VK_KHX_device_group[]
[open,refpage='VkMemoryAllocateFlagsInfoKHX',desc='Structure controlling how many instances of memory will be allocated',type='structs']
--
If the pname:pNext chain of slink:VkMemoryAllocateInfo includes a
sname:VkMemoryAllocateFlagsInfoKHX structure, then that structure includes
flags and a device mask controlling how many instances of the memory will be
allocated.
The sname:VkMemoryAllocateFlagsInfoKHX structure is defined as:
include::../api/structs/VkMemoryAllocateFlagsInfoKHX.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:flags is a bitmask of elink:VkMemoryAllocateFlagBitsKHX
controlling the allocation.
* pname:deviceMask is a mask of physical devices in the logical device,
indicating that memory must: be allocated on each device in the mask, if
ename:VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHX is set in pname:flags.
If ename:VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHX is not set, the number of
instances allocated depends on whether
ename:VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHX is set in the memory heap.
If ename:VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHX is set, then memory is
allocated for every physical device in the logical device (as if
pname:deviceMask has bits set for all device indices).
If ename:VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHX is not set, then a single
instance of memory is allocated (as if pname:deviceMask is set to one).
On some implementations, allocations from a multi-instance heap may: consume
memory on all physical devices even if the pname:deviceMask excludes some
devices.
If slink:VkPhysicalDeviceGroupPropertiesKHX::pname:subsetAllocation is
ename:VK_TRUE, then memory is only consumed for the devices in the device
mask.
[NOTE]
.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.
====
.Valid Usage
****
* [[VUID-VkMemoryAllocateFlagsInfoKHX-deviceMask-00675]]
If ename:VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHX is set, pname:deviceMask
must: be a valid device mask.
* [[VUID-VkMemoryAllocateFlagsInfoKHX-deviceMask-00676]]
If ename:VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHX is set, pname:deviceMask
must: not be zero
****
include::../validity/structs/VkMemoryAllocateFlagsInfoKHX.txt[]
--
[open,refpage='VkMemoryAllocateFlagBitsKHX',desc='Bitmask specifying flags for a device memory allocation',type='enums']
--
Bits which can: be set in slink:VkMemoryAllocateFlagsInfoKHX::pname:flags,
controlling device memory allocation, are:
include::../api/enums/VkMemoryAllocateFlagBitsKHX.txt[]
* ename:VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHX specifies that memory will
be allocated for the devices in
slink:VkMemoryAllocateFlagsInfoKHX::pname:deviceMask.
--
endif::VK_KHX_device_group[]
[open,refpage='vkFreeMemory',desc='Free GPU memory',type='protos']
--
To free a memory object, call:
include::../api/protos/vkFreeMemory.txt[]
* pname:device is the logical device that owns the memory.
* pname:memory is the sname:VkDeviceMemory object to be freed.
* pname:pAllocator controls host memory allocation as described in the
<<memory-allocation, 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_.
The memory can: remain bound to images or buffers at the time the memory
object is freed, but any further use of them (on host or device) for
anything other than destroying those objects will result in undefined
behavior.
If there are still any bound images or buffers, the memory may: not be
immediately released by the implementation, but must: be released by the
time all bound images and buffers have been destroyed.
Once memory is 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 <<resources-association, Resource Memory Association>> section.
If a memory object is mapped at the time it is freed, it is implicitly
unmapped.
[NOTE]
.Note
====
As described <<memory-device-unmap-does-not-flush, 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.
====
.Valid Usage
****
* [[VUID-vkFreeMemory-memory-00677]]
All submitted commands that refer to pname:memory (via images or
buffers) must: have completed execution
****
include::../validity/protos/vkFreeMemory.txt[]
--
[[memory-device-hostaccess]]
=== Host Access to Device Memory Objects
Memory objects created with flink:vkAllocateMemory are not directly host
accessible.
Memory objects created with the memory property
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT are considered _mappable_.
Memory objects must: be mappable in order to be successfully mapped on the
host.
[open,refpage='vkMapMemory',desc='Map a memory object into application address space',type='protos']
--
To retrieve a host virtual address pointer to a region of a mappable memory
object, call:
include::../api/protos/vkMapMemory.txt[]
* pname:device is the logical device that owns the memory.
* pname:memory is the sname:VkDeviceMemory object to be mapped.
* pname:offset is a zero-based byte offset from the beginning of the
memory object.
* pname:size is the size of the memory range to map, or
ename:VK_WHOLE_SIZE to map from pname:offset to the end of the
allocation.
* pname:flags is reserved for future use.
* pname:ppData points to a pointer in which is returned a host-accessible
pointer to the beginning of the mapped range.
This pointer minus pname:offset must: be aligned to at least
slink:VkPhysicalDeviceLimits::pname:minMemoryMapAlignment.
It is an application error to call fname:vkMapMemory on a memory object that
is already mapped.
[NOTE]
.Note
====
fname:vkMapMemory will fail if the implementation is unable to allocate an
appropriately sized contiguous virtual address range, e.g. due to virtual
address space fragmentation or platform limits.
In such cases, fname:vkMapMemory must: return
ename:VK_ERROR_MEMORY_MAP_FAILED.
The application can: improve the likelihood of success by reducing the size
of the mapped range and/or removing unneeded mappings using
fname:VkUnmapMemory.
====
[[memory-device-hostaccess-hazards]]
fname: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
<<synchronization-submission-host-writes, here>> for details on fulfilling
such a guarantee).
If the device memory was allocated without the
ename: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
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize, and round the end
of the range up to the nearest multiple of
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize.
While a range of device memory is mapped for host access, the application is
responsible for synchronizing both device and host access to that memory
range.
[NOTE]
.Note
====
It is important for the application developer to become meticulously
familiar with all of the mechanisms described in the chapter on
<<synchronization, Synchronization and Cache Control>> as they are crucial
to maintaining memory access ordering.
====
.Valid Usage
****
* [[VUID-vkMapMemory-memory-00678]]
pname:memory must: not be currently mapped
* [[VUID-vkMapMemory-offset-00679]]
pname:offset must: be less than the size of pname:memory
* [[VUID-vkMapMemory-size-00680]]
If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be
greater than `0`
* [[VUID-vkMapMemory-size-00681]]
If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be
less than or equal to the size of the pname:memory minus pname:offset
* [[VUID-vkMapMemory-memory-00682]]
pname:memory must: have been created with a memory type that reports
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
ifdef::VK_KHX_device_group[]
* [[VUID-vkMapMemory-memory-00683]]
pname:memory must: not have been allocated with multiple instances.
endif::VK_KHX_device_group[]
****
include::../validity/protos/vkMapMemory.txt[]
--
Two commands are provided to enable applications to work with non-coherent
memory allocations: fname:vkFlushMappedMemoryRanges and
fname:vkInvalidateMappedMemoryRanges.
[NOTE]
.Note
====
If the memory object was created with the
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT set,
fname:vkFlushMappedMemoryRanges and fname:vkInvalidateMappedMemoryRanges are
unnecessary and may: have a performance cost.
However, <<synchronization-dependencies-available-and-visible, availability
and visibility operations>> still need to be managed on the device.
See the description of <<synchronization-host-access-types, host access
types>> for more information.
====
[open,refpage='vkFlushMappedMemoryRanges',desc='Flush mapped memory ranges',type='protos']
--
To flush ranges of non-coherent memory from the host caches, call:
include::../api/protos/vkFlushMappedMemoryRanges.txt[]
* pname:device is the logical device that owns the memory ranges.
* pname:memoryRangeCount is the length of the pname:pMemoryRanges array.
* pname:pMemoryRanges is a pointer to an array of
slink:VkMappedMemoryRange structures describing the memory ranges to
flush.
fname:vkFlushMappedMemoryRanges guarantees that host writes to the memory
ranges described by pname:pMemoryRanges can: be made available to device
access, via <<synchronization-dependencies-available-and-visible,
availability operations>> from the ename:VK_ACCESS_HOST_WRITE_BIT
<<synchronization-access-types,access type>>.
[[memory-device-unmap-does-not-flush]]
Unmapping non-coherent memory does not implicitly flush the 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]
.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).
====
include::../validity/protos/vkFlushMappedMemoryRanges.txt[]
--
[open,refpage='vkInvalidateMappedMemoryRanges',desc='Invalidate ranges of mapped memory objects',type='protos']
--
To invalidate ranges of non-coherent memory from the host caches, call:
include::../api/protos/vkInvalidateMappedMemoryRanges.txt[]
* pname:device is the logical device that owns the memory ranges.
* pname:memoryRangeCount is the length of the pname:pMemoryRanges array.
* pname:pMemoryRanges is a pointer to an array of
slink:VkMappedMemoryRange structures describing the memory ranges to
invalidate.
fname:vkInvalidateMappedMemoryRanges guarantees that device writes to the
memory ranges described by pname:pMemoryRanges, which have been made visible
to the ename:VK_ACCESS_HOST_WRITE_BIT and ename:VK_ACCESS_HOST_READ_BIT
<<synchronization-access-types, 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.
[NOTE]
.Note
====
Mapping non-coherent memory does not implicitly invalidate the mapped
memory, and device writes that have not been invalidated must: be made
visible before the host reads or overwrites them.
====
include::../validity/protos/vkInvalidateMappedMemoryRanges.txt[]
--
[open,refpage='VkMappedMemoryRange',desc='Structure specifying a mapped memory range',type='structs']
--
The sname:VkMappedMemoryRange structure is defined as:
include::../api/structs/VkMappedMemoryRange.txt[]
* pname:sType is the type of this structure.
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
* pname:memory is the memory object to which this range belongs.
* pname:offset is the zero-based byte offset from the beginning of the
memory object.
* pname:size is either the size of range, or ename:VK_WHOLE_SIZE to affect
the range from pname:offset to the end of the current mapping of the
allocation.
.Valid Usage
****
* [[VUID-VkMappedMemoryRange-memory-00684]]
pname:memory must: be currently mapped
* [[VUID-VkMappedMemoryRange-size-00685]]
If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:offset and
pname:size must: specify a range contained within the currently mapped
range of pname:memory
* [[VUID-VkMappedMemoryRange-size-00686]]
If pname:size is equal to ename:VK_WHOLE_SIZE, pname:offset must: be
within the currently mapped range of pname:memory
* [[VUID-VkMappedMemoryRange-size-01389]]
If pname:size is equal to ename:VK_WHOLE_SIZE, the end of the current
mapping of pname:memory must: be a multiple of
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize bytes from the
beginning of the memory object.
* [[VUID-VkMappedMemoryRange-offset-00687]]
pname:offset must: be a multiple of
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize
* [[VUID-VkMappedMemoryRange-size-01390]]
If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must:
either be a multiple of
slink:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize, or pname:offset
plus pname:size must: equal the size of pname:memory.
****
include::../validity/structs/VkMappedMemoryRange.txt[]
--
[open,refpage='vkUnmapMemory',desc='Unmap a previously mapped memory object',type='protos']
--
To unmap a memory object once host access to it is no longer needed by the
application, call:
include::../api/protos/vkUnmapMemory.txt[]
* pname:device is the logical device that owns the memory.
* pname:memory is the memory object to be unmapped.
.Valid Usage
****
* [[VUID-vkUnmapMemory-memory-00689]]
pname:memory must: be currently mapped
****
include::../validity/protos/vkUnmapMemory.txt[]
--
[[memory-device-lazy_allocation]]
=== Lazily Allocated Memory
If the memory object is allocated from a heap with the
ename: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
sname:VkImage whose usage flags include
ename:VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT.
[NOTE]
.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.
====
[open,refpage='vkGetDeviceMemoryCommitment',desc='Query the current commitment for a VkDeviceMemory',type='protos']
--
To determine the amount of lazily-allocated memory that is currently
committed for a memory object, call:
include::../api/protos/vkGetDeviceMemoryCommitment.txt[]
* pname:device is the logical device that owns the memory.
* pname:memory is the memory object being queried.
* pname:pCommittedMemoryInBytes is a pointer to a basetype: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.
.Valid Usage
****
* [[VUID-vkGetDeviceMemoryCommitment-memory-00690]]
pname:memory must: have been created with a memory type that reports
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
****
include::../validity/protos/vkGetDeviceMemoryCommitment.txt[]
--
ifdef::VK_KHX_device_group[]
[[memory-peer-memory-features]]
=== Peer Memory Features
[open,refpage='vkGetDeviceGroupPeerMemoryFeaturesKHX',desc='Query supported peer memory features of a device',type='protos']
--
_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:
include::../api/protos/vkGetDeviceGroupPeerMemoryFeaturesKHX.txt[]
* pname:device is the logical device that owns the memory.
* pname:heapIndex is the index of the memory heap from which the memory is
allocated.
* pname:localDeviceIndex is the device index of the physical device that
performs the memory access.
* pname:remoteDeviceIndex is the device index of the physical device that
the memory is allocated for.
* pname:pPeerMemoryFeatures is a pointer to a bitmask of
elink:VkPeerMemoryFeatureFlagBitsKHX indicating which types of memory
accesses are supported for the combination of heap, local, and remote
devices.
.Valid Usage
****
* [[VUID-vkGetDeviceGroupPeerMemoryFeaturesKHX-heapIndex-00691]]
pname:heapIndex must: be less than pname:memoryHeapCount
* [[VUID-vkGetDeviceGroupPeerMemoryFeaturesKHX-localDeviceIndex-00692]]
pname:localDeviceIndex must: be a valid device index
* [[VUID-vkGetDeviceGroupPeerMemoryFeaturesKHX-remoteDeviceIndex-00693]]
pname:remoteDeviceIndex must: be a valid device index
* [[VUID-vkGetDeviceGroupPeerMemoryFeaturesKHX-localDeviceIndex-00694]]
pname:localDeviceIndex must: not equal remoteDeviceIndex
****
include::../validity/protos/vkGetDeviceGroupPeerMemoryFeaturesKHX.txt[]
--
[open,refpage='VkPeerMemoryFeatureFlagBitsKHX',desc='Bitmask specifying supported peer memory features',type='enums']
--
Bits which may: be set in the value returned for
flink:vkGetDeviceGroupPeerMemoryFeaturesKHX::pname:pPeerMemoryFeatures,
indicating the supported peer memory features, are:
include::../api/enums/VkPeerMemoryFeatureFlagBitsKHX.txt[]
* ename:VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHX indicates that the memory
can: be accessed as the source of a ftext:vkCmdCopyBuffer,
ftext:vkCmdCopyImage, ftext:vkCmdCopyBufferToImage, or
ftext:vkCmdCopyImageToBuffer command.
* ename:VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHX indicates that the memory
can: be accessed as the destination of a ftext:vkCmdCopyBuffer,
ftext:vkCmdCopyImage, ftext:vkCmdCopyBufferToImage, or
ftext:vkCmdCopyImageToBuffer command.
* ename:VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHX indicates that the
memory can: be read as any memory access type.
* ename:VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHX indicates that the
memory can: be written as any memory access type.
Shader atomics are considered to be writes.
ename:VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHX must: be supported for all
host local heaps and for at least one device local 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.
--
endif::VK_KHX_device_group[]