// Copyright (c) 2015-2017 The Khronos Group Inc. // Copyright notice at https://www.khronos.org/registry/speccopyright.html [[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. // refBegin VkAllocationCallbacks Structure containing callback function pointers for memory allocation 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 pointer to a valid user-defined tlink:PFN_vkAllocationFunction * [[VUID-VkAllocationCallbacks-pfnReallocation-00633]] pname:pfnReallocation must: be a pointer to a valid user-defined tlink:PFN_vkReallocationFunction * [[VUID-VkAllocationCallbacks-pfnFree-00634]] pname:pfnFree must: be a 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[] // refBegin PFN_vkAllocationFunction Application-defined memory allocation function 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 <>. [[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 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 <>. 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. // refEnd PFN_vkAllocationFunction VkAllocationCallbacks // refBegin PFN_vkReallocationFunction Application-defined memory reallocation function 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 <>. 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 <>. // refEnd PFN_vkReallocationFunction VkAllocationCallbacks // refBegin PFN_vkFreeFunction Application-defined memory free function 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. // refEnd PFN_vkFreeFunction VkAllocationCallbacks // refBegin PFN_vkInternalAllocationNotification Application-defined memory allocation notification function 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 <>. This is a purely informational callback. // refEnd PFN_vkInternalAllocationNotification VkAllocationCallbacks // refBegin PFN_vkInternalFreeNotification Application-defined memory free notification function 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 <>. // refEnd PFN_vkInternalFreeNotification VkAllocationCallbacks // refBegin VkSystemAllocationScope Allocation scope [[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 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 sname:VkPipelineCache, the allocator will use the ename:VK_SYSTEM_ALLOCATION_SCOPE_CACHE allocation scope. The most specific allocator available is used (pipeline 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. // refEnd VkSystemAllocationScope VkAllocationCallbacks 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. // refBegin VkInternalAllocationType Allocation type 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. // refEnd VkInternalAllocationType PFN_vkInternalAllocationNotification PFN_vkInternalFreeNotification 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:pPipelineCache ** fname:vkCreateComputePipelines for pname:pPipelineCache * 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. * 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 opaque images that can: be natively used by the device, or uniform buffer objects that reside in on-device memory. Memory properties of a physical device describe the memory heaps and memory types available. // refBegin vkGetPhysicalDeviceMemoryProperties Reports memory information for the specified physical device 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[] // refBegin VkPhysicalDeviceMemoryProperties Structure specifying physical device memory properties 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 sname: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 sname: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. 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. The memory types are sorted according to a preorder which serves to aid in easily selecting an appropriate memory type. Given two memory types X and Y, the preorder defines [eq]#X {leq} Y# if: * the memory property bits set for X are a strict subset of the memory property bits set for Y. Or, * the memory property bits set for X are the same as the memory property bits set for Y, and X uses a memory heap with greater or equal performance (as determined in an implementation-specific manner). Memory types are ordered in the list such that X is assigned a lesser pname:memoryTypeIndex than Y if [eq]#(X {leq} Y) {land} {lnot} (Y {leq} X)# according to the preorder. Note that the list of all allowed memory property flag combinations above satisfies this preorder, but other orders would as well. The goal of this ordering is to enable applications to use a simple search loop in selecting the proper memory type, along the lines of: [source,c++] --------------------------------------------------- // Find a memory type in "memoryTypeBits" that includes all of "properties" int32_t FindProperties(uint32_t memoryTypeBits, VkMemoryPropertyFlags properties) { for (int32_t i = 0; i < memoryTypeCount; ++i) { if ((memoryTypeBits & (1 << i)) && ((memoryTypes[i].propertyFlags & properties) == properties)) return i; } return -1; } // Try to find an optimal memory type, or if it does not exist // find any compatible memory type VkMemoryRequirements memoryRequirements; vkGetImageMemoryRequirements(device, image, &memoryRequirements); int32_t memoryType = FindProperties(memoryRequirements.memoryTypeBits, optimalProperties); if (memoryType == -1) memoryType = FindProperties(memoryRequirements.memoryTypeBits, requiredProperties); --------------------------------------------------- The loop will find the first supported memory type that has all bits requested in code:properties set. If there is no exact match, it will find a closest match (i.e. a memory type with the fewest additional bits set), which has some additional bits set but which are not detrimental to the behaviors requested by code:properties. The application can: first search for the optimal properties, e.g. a memory type that is device-local or supports coherent cached accesses, as appropriate for the intended usage, and if such a memory type is not present can: fallback to searching for a less optimal but guaranteed set of properties such as "0" or "host-visible and coherent". include::../validity/structs/VkPhysicalDeviceMemoryProperties.txt[] ifdef::VK_KHR_get_physical_device_properties2[] // refBegin vkGetPhysicalDeviceMemoryProperties2KHR Reports memory information for the specified physical device 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[] // refBegin VkPhysicalDeviceMemoryProperties2KHR Structure specifying physical device memory properties 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[] // refBegin VkMemoryHeap Structure specifying a memory heap 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[] // refBegin VkMemoryHeapFlagBits Bitmask specifying attribute flags for a heap 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[] // refEnd VkMemoryHeapFlagBits // refBegin VkMemoryType Structure specifying memory type 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 sname:VkPhysicalDeviceMemoryProperties structure. * pname:propertyFlags is a bitmask of elink:VkMemoryPropertyFlagBits of properties for this memory type. include::../validity/structs/VkMemoryType.txt[] // refBegin VkMemoryPropertyFlagBits Bitmask specifying properties for a memory type 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 only be set for memory types belonging to heaps 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 <>. // refEnd VkMemoryPropertyFlagBits // refBegin VkDeviceMemory Opaque handle to a device memory object A Vulkan device operates on data in device memory via memory objects that are represented in the API by a sname:VkDeviceMemory handle. Memory objects are represented by sname:VkDeviceMemory handles: include::../api/handles/VkDeviceMemory.txt[] // refEnd VkDeviceMemory // refBegin vkAllocateMemory Allocate GPU memory 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 <> 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 by 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. There is an implementation-dependent maximum number of memory allocations which can: be simultaneously created on a device. This is specified by the <> member of the sname:VkPhysicalDeviceLimits structure. If pname:maxMemoryAllocationCount is exceeded, fname:vkAllocateMemory will return ename:VK_ERROR_TOO_MANY_OBJECTS. [NOTE] .Note ==== 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 should: be returned. ==== .Valid Usage **** * [[VUID-vkAllocateMemory-device-00636]] The number of currently valid memory objects, allocated from pname:device, must: be less than sname:VkPhysicalDeviceLimits::pname:maxMemoryAllocationCount **** include::../validity/protos/vkAllocateMemory.txt[] // refBegin VkMemoryAllocateInfo Structure containing parameters of a memory allocation 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 the memory type index, which selects the properties of the memory to be allocated, as well as the heap the memory will come from. ifdef::VK_KHX_external_memory_win32,VK_KHX_external_memory_fd[] If the pname:pNext chain contains an instance of ifdef::VK_KHX_external_memory_win32[] slink:VkImportMemoryWin32HandleInfoKHX with a non-zero value for sname:VkImportMemoryWin32HandleInfoKHX::pname:handleType, endif::VK_KHX_external_memory_win32[] ifdef::VK_KHX_external_memory_win32+VK_KHX_external_memory_fd[] or endif::VK_KHX_external_memory_win32+VK_KHX_external_memory_fd[] ifdef::VK_KHX_external_memory_fd[] slink:VkImportMemoryFdInfoKHX with a non-zero value for sname:VkImportMemoryFdInfoKHX::pname:handleType, endif::VK_KHX_external_memory_fd[] the slink:VkMemoryAllocateInfo instance defines a memory import operation. 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_KHX. endif::VK_KHX_external_memory_win32,VK_KHX_external_memory_fd[] .Valid Usage **** * [[VUID-VkMemoryAllocateInfo-allocationSize-00637]] pname:allocationSize must: be less than or equal to the amount of memory available to the sname:VkMemoryHeap specified by pname:memoryTypeIndex and the calling command's sname:VkDevice * [[VUID-VkMemoryAllocateInfo-allocationSize-00638]] pname:allocationSize must: be greater than `0` ifdef::VK_KHX_external_memory+VK_NV_dedicated_allocation[] * [[VUID-VkMemoryAllocateInfo-pNext-00639]] If the pname:pNext chain contains an instance of sname:VkExportMemoryAllocateInfoKHX, and any of the handle types specified in sname:VkExportMemoryAllocateInfoKHX::pname:handleTypes require a dedicated allocation, as reported by flink:vkGetPhysicalDeviceImageFormatProperties2KHR in sname:VkExternalImageFormatPropertiesKHX::pname:externalMemoryProperties::pname:externalMemoryFeatures or sname:VkExternalBufferPropertiesKHX::pname:externalMemoryProperties::pname:externalMemoryFeatures, the pname:pNext chain must: contain an instance of sname:VkDedicatedAllocationMemoryAllocateInfoNV with either its pname:image or pname:buffer field set to a value other than ename:VK_NULL_HANDLE. endif::VK_KHX_external_memory+VK_NV_dedicated_allocation[] ifdef::VK_KHX_external_memory+VK_NV_external_memory[] * [[VUID-VkMemoryAllocateInfo-pNext-00640]] If the pname:pNext chain contains an instance of slink:VkExportMemoryAllocateInfoKHX, it must: not contain an instance of slink:VkExportMemoryAllocateInfoNV or slink:VkExportMemoryWin32HandleInfoNV. endif::VK_KHX_external_memory+VK_NV_external_memory[] ifdef::VK_KHX_external_memory_win32+VK_NV_external_memory_win32[] * [[VUID-VkMemoryAllocateInfo-pNext-00641]] If the pname:pNext chain contains an instance of slink:VkImportMemoryWin32HandleInfoKHX, it must: not contain an instance of slink:VkImportMemoryWin32HandleInfoNV. endif::VK_KHX_external_memory_win32+VK_NV_external_memory_win32[] ifdef::VK_KHX_external_memory_win32,VK_KHX_external_memory_fd[] * [[VUID-VkMemoryAllocateInfo-allocationSize-00642]] If the parameters define an import operation and the external handle specified was created by the Vulkan API, the values of pname:allocationSize and pname:memoryTypeIndex must: match those specified when the memory object being imported was created. endif::VK_KHX_external_memory_win32,VK_KHX_external_memory_fd[] ifdef::VK_KHX_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_KHX_external_memory+VK_KHX_device_group[] ifdef::VK_KHX_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 slink:vkGetMemoryWin32HandlePropertiesKHX. * [[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_KHX, ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHX, or ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHX, 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_KHX, pname:allocationSize must: match the size specified when creating the Direct3D 12 heap from which the external handle was extracted. endif::VK_KHX_external_memory_win32[] ifdef::VK_KHX_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 slink:vkGetMemoryFdPropertiesKHX. endif::VK_KHX_external_memory_fd[] **** include::../validity/structs/VkMemoryAllocateInfo.txt[] ifdef::VK_NV_dedicated_allocation[] // refBegin VkDedicatedAllocationMemoryAllocateInfoNV Specify a dedicated memory allocation resource If the pname:pNext list 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 sname:VK_NULL_HANDLE or a handle of an image which this memory will be bound to. * pname:buffer is sname: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 sname:VK_NULL_HANDLE * [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00650]] If pname:image is not sname: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 sname: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 sname: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 sname:VK_NULL_HANDLE, sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the sname:VkMemoryRequirements::pname:size of the buffer ifdef::VK_KHX_external_memory_win32,VK_KHX_external_memory_fd[] * [[VUID-VkDedicatedAllocationMemoryAllocateInfoNV-image-00654]] If pname:image is not sname: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 sname: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_KHX_external_memory_win32,VK_KHX_external_memory_fd[] **** include::../validity/structs/VkDedicatedAllocationMemoryAllocateInfoNV.txt[] endif::VK_NV_dedicated_allocation[] ifdef::VK_KHX_external_memory[] // refBegin VkExportMemoryAllocateInfoKHX Specify exportable handle types for a device memory object When allocating memory that may: be exported to another process or Vulkan instance, add a slink:VkExportMemoryAllocateInfoKHX structure to the pname:pNext chain of the slink:VkMemoryAllocateInfo structure, specifying the handle types that may: be exported. The slink:VkExportMemoryAllocateInfoKHX structure is defined as: include::../api/structs/VkExportMemoryAllocateInfoKHX.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:VkExternalMemoryHandleTypeFlagBitsKHX 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-VkExportMemoryAllocateInfoKHX-handleTypes-00656]] The bits in pname:handleTypes must: be supported and compatible, as reported by slink:VkExternalImageFormatPropertiesKHX or slink:VkExternalBufferPropertiesKHX. **** include::../validity/structs/VkExportMemoryAllocateInfoKHX.txt[] endif::VK_KHX_external_memory[] ifdef::VK_KHX_external_memory_win32[] // refBegin VkExportMemoryWin32HandleInfoKHX Structure specifying additional attributes of Windows handles exported from a memory To specify additional attributes of NT handles exported from a memory object, add the slink:VkExportMemoryWin32HandleInfoKHX structure to the pname:pNext chain of the slink:VkMemoryAllocateInfo structure. The sname:VkExportMemoryWin32HandleInfoKHX structure is defined as: include::../api/structs/VkExportMemoryWin32HandleInfoKHX.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_KHX ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHX And code:GENERIC_ALL for handles of the following types: ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHX ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHX 1:: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686670.aspx .Valid Usage **** * [[VUID-VkExportMemoryWin32HandleInfoKHX-handleTypes-00657]] If slink:VkExportMemoryAllocateInfoKHX::pname:handleTypes does not include ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHX, ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHX, ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHX, or ename:VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHX, VkExportMemoryWin32HandleInfoKHX must: not be in the pname:pNext chain of slink:VkMemoryAllocateInfo. **** include::../validity/structs/VkExportMemoryWin32HandleInfoKHX.txt[] // refBegin VkImportMemoryWin32HandleInfoKHX - import Win32 memory created on the same physical device To import memory created on the same underlying physical device but outside of the current Vulkan instance from a Windows handle, add a slink:VkImportMemoryWin32HandleInfoKHX structure to the pname:pNext chain of the slink:VkMemoryAllocateInfo structure. The sname:VkImportMemoryWin32HandleInfoKHX structure is defined as: include::../api/structs/VkImportMemoryWin32HandleInfoKHX.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. * pname:handle is the external handle to import. 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 fname:CloseHandle system call when the handle is no longer needed. .Valid Usage **** * [[VUID-VkImportMemoryWin32HandleInfoKHX-handleType-00658]] If pname:handleType is not `0`, it must: be supported for import, as reported by slink:VkExternalImageFormatPropertiesKHX or slink:VkExternalBufferPropertiesKHX. * [[VUID-VkImportMemoryWin32HandleInfoKHX-handle-00659]] The memory from which pname:handle was exported must: have been created on the same underlying physical device as pname:device. * [[VUID-VkImportMemoryWin32HandleInfoKHX-handleType-00660]] If pname:handleType is not `0`, it must: be defined as an NT handle or a global share handle. * [[VUID-VkImportMemoryWin32HandleInfoKHX-handleType-00661]] If pname:handleType is not `0`, pname:handle must: be a valid handle of the type specified by pname:handleType. **** include::../validity/structs/VkImportMemoryWin32HandleInfoKHX.txt[] // refBegin vkGetMemoryWin32HandleKHX Get a Windows HANDLE for a memory object To export a Windows handle representing the underlying resources of a Vulkan device memory object, call: include::../api/protos/vkGetMemoryWin32HandleKHX.txt[] * pname:device is the logical device that created pname:memory. * pname:memory is the memory object from which the handle will be exported. * pname:handleType is the type of handle requested. * pname:pHandle will return the Windows handle representing the underlying resources of the device memory object. The properties of the handle returned depend on the value of pname:handleType. See elink:VkExternalMemoryHandleTypeFlagBitsKHX for a description of the properties of the defined external memory handle types. For handle types defined as NT handles, the handles returned by fname:vkGetMemoryWin32HandleKHX are owned by the application. To avoid leaking resources, the application must: release ownership of them using the fname:CloseHandle system call when they are no longer needed. .Valid Usage **** * [[VUID-vkGetMemoryWin32HandleKHX-handleType-00662]] pname:handleType must: have been included in slink:VkExportMemoryAllocateInfoKHX::pname:handleTypes when pname:memory was created. * [[VUID-vkGetMemoryWin32HandleKHX-handleType-00663]] If pname:handleType is defined as an NT handle, flink:vkGetMemoryWin32HandleKHX must: be called no more than once for each valid unique combination of pname:memory and pname:handleType. * [[VUID-vkGetMemoryWin32HandleKHX-handleType-00664]] pname:handleType must: be defined as an NT handle or a global share handle. **** include::../validity/protos/vkGetMemoryWin32HandleKHX.txt[] // refBegin vkGetMemoryWin32HandlePropertiesKHX Get Properties of External Memory Win32 Handles 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/vkGetMemoryWin32HandlePropertiesKHX.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-vkGetMemoryWin32HandlePropertiesKHX-handle-00665]] pname:handle must: be an external memory handle created outside of the Vulkan API. * [[VUID-vkGetMemoryWin32HandlePropertiesKHX-handleType-00666]] pname:handleType must: not be one of the handle types defined as opaque. **** include::../validity/protos/vkGetMemoryWin32HandlePropertiesKHX.txt[] // refEnd vkGetMemoryWin32HandlePropertiesKHX // refBegin VkMemoryWin32HandlePropertiesKHX Properties of External Memory Windows Handles The sname:VkMemoryWin32HandlePropertiesKHX structure returned is defined as: include::../api/structs/VkMemoryWin32HandlePropertiesKHX.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. // refEnd VkMemoryWin32HandlePropertiesKHX endif::VK_KHX_external_memory_win32[] ifdef::VK_KHX_external_memory_fd[] // refBegin VkImportMemoryFdInfoKHX - import memory created on the same physical device from a file descriptor To import memory created on the same underlying physical device but outside of the current Vulkan instance from a POSIX file descriptor handle, add a slink:VkImportMemoryFdInfoKHX structure to the pname:pNext chain of the slink:VkMemoryAllocateInfo structure. The sname:VkImportMemoryFdInfoKHX structure is defined as: include::../api/structs/VkImportMemoryFdInfoKHX.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. .Valid Usage **** * [[VUID-VkImportMemoryFdInfoKHX-handleType-00667]] If pname:handleType is not `0`, it must: be supported for import, as reported by slink:VkExternalImageFormatPropertiesKHX or slink:VkExternalBufferPropertiesKHX. * [[VUID-VkImportMemoryFdInfoKHX-fd-00668]] The memory from which pname:fd was exported must: have been created on the same underlying physical device as pname:device. * [[VUID-VkImportMemoryFdInfoKHX-handleType-00669]] If pname:handleType is not `0`, it must: be defined as a POSIX file descriptor handle. * [[VUID-VkImportMemoryFdInfoKHX-handleType-00670]] If pname:handleType is not `0`, pname:fd must: be a valid handle of the type specified by pname:handleType. **** include::../validity/structs/VkImportMemoryFdInfoKHX.txt[] // refBegin vkGetMemoryFdKHX Get a POSIX file descriptor for a memory object To export a POSIX file descriptor representing the underlying resources of a Vulkan device memory object, call: include::../api/protos/vkGetMemoryFdKHX.txt[] * pname:device is the logical device that created pname:memory. * pname:memory is the memory object from which the handle will be exported. * pname:handleType is the type of handle requested. * pname:pFd will return a file descriptor representing the underlying resources of the device memory object. The properties of the file descriptor returned depend on the value of pname:handleType. See elink:VkExternalMemoryHandleTypeFlagBitsKHX for a description of the properties of the defined external memory handle types. Each call to fname:vkGetMemoryFdKHX 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 fname:close system call when it is no longer needed, or by importing a Vulkan memory object from it. .Valid Usage **** * [[VUID-vkGetMemoryFdKHX-handleType-00671]] pname:handleType must: have been included in slink:VkExportMemoryAllocateInfoKHX::pname:handleTypes when pname:memory was created. * [[VUID-vkGetMemoryFdKHX-handleType-00672]] pname:handleType must: be defined as a POSIX file descriptor handle. **** include::../validity/protos/vkGetMemoryFdKHX.txt[] // refBegin vkGetMemoryFdPropertiesKHX Get Properties of External Memory File Descriptors 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/vkGetMemoryFdPropertiesKHX.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-vkGetMemoryFdPropertiesKHX-fd-00673]] pname:fd must: be an external memory handle created outside of the Vulkan API. * [[VUID-vkGetMemoryFdPropertiesKHX-handleType-00674]] pname:handleType must: not be one of the handle types defined as opaque. **** include::../validity/protos/vkGetMemoryFdPropertiesKHX.txt[] // refEnd vkGetMemoryFdPropertiesKHX // refBegin VkMemoryFdPropertiesKHX Properties of External Memory File Descriptors The sname:VkMemoryFdPropertiesKHX structure returned is defined as: include::../api/structs/VkMemoryFdPropertiesKHX.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. // refEnd VkMemoryFdPropertiesKHX endif::VK_KHX_external_memory_fd[] 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[] // refBegin VkMemoryAllocateFlagsInfoKHX Structure controlling how many instances of memory will be allocated If the pname:pNext list 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[] // refBegin VkMemoryAllocateFlagBitsKHX Bitmask specifying flags for a device memory allocation 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. // refEnd VkMemoryAllocateFlagBitsKHX endif::VK_KHX_device_group[] // refBegin vkFreeMemory Free GPU memory 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 <> 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 queued for execution. 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 <> section. If a memory object is mapped at the time it is freed, it is implicitly unmapped. .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 fname: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. // refBegin vkMapMemory Map a memory object into application address space 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 sname: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 <> 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 sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize, and round the end of the range up to the nearest multiple of sname: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 <> as they are crucial to maintaining memory access ordering. ==== .Valid Usage **** * [[VUID-vkMapMemory-memory-00678]] pname:memory must: not currently be 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, <> still need to be managed on the device. See the description of <> for more information. ==== // refBegin vkFlushMappedMemoryRanges Flush mapped memory ranges 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 <> from the ename:VK_ACCESS_HOST_WRITE_BIT <>. [NOTE] .Note ==== 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. ==== include::../validity/protos/vkFlushMappedMemoryRanges.txt[] // refBegin vkInvalidateMappedMemoryRanges Invalidate ranges of mapped memory objects 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 <>, 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[] // refBegin VkMappedMemoryRange Structure specifying a mapped memory range 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: currently be 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 sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize bytes from the beginning of the memory object. * [[VUID-VkMappedMemoryRange-offset-00687]] pname:offset must: be a multiple of sname: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 sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize, or pname:offset plus pname:size must: equal the size of pname:memory. **** include::../validity/structs/VkMappedMemoryRange.txt[] // refBegin vkUnmapMemory Unmap a previously mapped memory object 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: currently be 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. ==== // refBegin vkGetDeviceMemoryCommitment Query the current commitment for a VkDeviceMemory 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 // refBegin vkGetDeviceGroupPeerMemoryFeaturesKHX Query supported peer memory features of a device _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[] // refEnd vkGetDeviceGroupPeerMemoryFeaturesKHX // refBegin VkPeerMemoryFeatureFlagBitsKHX Bitmask specifying supported peer memory features 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:vkCmdCopy* command. * ename:VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHX indicates that the memory can: be accessed as the destination of a ftext:vkCmdCopy* command. * ename:VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHX indicates that the memory can: be read as any other memory access type. * ename:VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHX indicates that the memory can: be written as any other memory access type. Shader atomics are considered to be writes. ename:VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHX must: be supported for all heaps. 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. // refEnd VkPeerMemoryFeatureFlagBitsKHX endif::VK_KHX_device_group[]