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.
Vulkan provides applications the opportunity to perform host memory allocations on behalf of the Vulkan implementation. If this feature is not used, the implementation will perform its own memory allocations. Since most memory allocations are off the critical path, this is not meant as a performance feature. Rather, this can be useful for certain embedded systems, for debugging purposes (e.g. putting a guard page after all host allocations), or for memory allocation logging.
Allocators are provided by the application as a pointer to a
VkAllocationCallbacks structure:
typedef struct VkAllocationCallbacks {
void* pUserData;
PFN_vkAllocationFunction pfnAllocation;
PFN_vkReallocationFunction pfnReallocation;
PFN_vkFreeFunction pfnFree;
PFN_vkInternalAllocationNotification pfnInternalAllocation;
PFN_vkInternalFreeNotification pfnInternalFree;
} VkAllocationCallbacks;
pUserData is a value to be interpreted by the implementation of
the callbacks.
When any of the callbacks in 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.
pfnAllocation is a pointer to an application-defined memory
allocation function of type PFN_vkAllocationFunction.
pfnReallocation is a pointer to an application-defined memory
reallocation function of type PFN_vkReallocationFunction.
pfnFree is a pointer to an application-defined memory free
function of type PFN_vkFreeFunction.
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
PFN_vkInternalAllocationNotification.
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
PFN_vkInternalFreeNotification.
The type of pfnAllocation is:
typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)(
void* pUserData,
size_t size,
size_t alignment,
VkSystemAllocationScope allocationScope);
pUserData is the value specified for
VkAllocationCallbacks::pUserData in the allocator specified
by the application.
size is the size in bytes of the requested allocation.
alignment is the requested alignment of the allocation in bytes
and must be a power of two.
allocationScope is a VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described here.
If pfnAllocation is unable to allocate the requested memory, it must
return NULL.
If the allocation was successful, it must return a valid pointer to memory
allocation containing at least size bytes, and with the pointer value
being a multiple of alignment.
| Note | |
|---|---|
Correct Vulkan operation cannot be assumed if the application does not follow these rules. For example, |
If pfnAllocation returns NULL, and if the implementation is unable
to continue correct processing of the current command without the requested
allocation, it must treat this as a run-time error, and generate
VK_ERROR_OUT_OF_HOST_MEMORY at the appropriate time for the command in
which the condition was detected, as described in Return Codes.
If the implementation is able to continue correct processing of the current
command without the requested allocation, then it may do so, and must not
generate VK_ERROR_OUT_OF_HOST_MEMORY as a result of this failed
allocation.
The type of pfnReallocation is:
typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)(
void* pUserData,
void* pOriginal,
size_t size,
size_t alignment,
VkSystemAllocationScope allocationScope);
pUserData is the value specified for
VkAllocationCallbacks::pUserData in the allocator specified
by the application.
pOriginal must be either NULL or a pointer previously returned
by pfnReallocation or pfnAllocation of the same allocator.
size is the size in bytes of the requested allocation.
alignment is the requested alignment of the allocation in bytes
and must be a power of two.
allocationScope is a VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described here.
pfnReallocation must return an allocation with enough space for
size bytes, and the contents of the original allocation from bytes
zero to min(original size, new size) - 1 must be preserved in the
returned allocation.
If size is larger than the old size, the contents of the additional
space are undefined.
If satisfying these requirements involves creating a new allocation, then
the old allocation should be freed.
If pOriginal is NULL, then pfnReallocation must behave
equivalently to a call to PFN_vkAllocationFunction with the same
parameter values (without pOriginal).
If size is zero, then pfnReallocation must behave equivalently
to a call to PFN_vkFreeFunction with the same pUserData
parameter value, and pMemory equal to pOriginal.
If pOriginal is non-NULL, the implementation must ensure that
alignment is equal to the alignment used to originally allocate
pOriginal.
If this function fails and pOriginal is non-NULL the application
must not free the old allocation.
pfnReallocation must follow the same
rules for return values as PFN_vkAllocationFunction.
The type of pfnFree is:
typedef void (VKAPI_PTR *PFN_vkFreeFunction)(
void* pUserData,
void* pMemory);
pUserData is the value specified for
VkAllocationCallbacks::pUserData in the allocator specified
by the application.
pMemory is the allocation to be freed.
pMemory may be NULL, which the callback must handle safely.
If pMemory is non-NULL, it must be a pointer previously allocated
by pfnAllocation or pfnReallocation.
The application should free this memory.
The type of pfnInternalAllocation is:
typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)(
void* pUserData,
size_t size,
VkInternalAllocationType allocationType,
VkSystemAllocationScope allocationScope);
pUserData is the value specified for
VkAllocationCallbacks::pUserData in the allocator specified
by the application.
size is the requested size of an allocation.
allocationType is the requested type of an allocation.
allocationScope is a VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described here.
This is a purely informational callback.
The type of pfnInternalFree is:
typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)(
void* pUserData,
size_t size,
VkInternalAllocationType allocationType,
VkSystemAllocationScope allocationScope);
pUserData is the value specified for
VkAllocationCallbacks::pUserData in the allocator specified
by the application.
size is the requested size of an allocation.
allocationType is the requested type of an allocation.
allocationScope is a VkSystemAllocationScope value
specifying the allocation scope of the lifetime of the allocation, as
described here.
Each allocation has an allocation scope which defines its lifetime and
which object it is associated with.
The allocation scope is provided in the allocationScope parameter
passed to callbacks defined in VkAllocationCallbacks.
Possible values for this parameter are defined by
VkSystemAllocationScope:
typedef enum VkSystemAllocationScope {
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1,
VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2,
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3,
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4,
} VkSystemAllocationScope;
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND - The allocation is scoped to
the duration of the Vulkan command.
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT - The allocation is scoped to
the lifetime of the Vulkan object that is being created or used.
VK_SYSTEM_ALLOCATION_SCOPE_CACHE - The allocation is scoped to the
lifetime of a VkPipelineCache object.
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE - The allocation is scoped to
the lifetime of the Vulkan device.
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE - The allocation is scoped to
the lifetime of the Vulkan instance.
Most Vulkan commands operate on a single object, or there is a sole object
that is being created or manipulated.
When an allocation uses an allocation scope of
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT or
VK_SYSTEM_ALLOCATION_SCOPE_CACHE, the allocation is scoped to the
object being created or manipulated.
When an implementation requires host memory, it will make callbacks to the application using the most specific allocator and allocation scope available:
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 VkDevice has an allocator it will be
used, else if the parent VkInstance has an allocator it will be
used.
Else,
VkPipelineCache, the allocator will use the
VK_SYSTEM_ALLOCATION_SCOPE_CACHE allocation scope.
The most specific allocator available is used (pipeline cache, else
device, else instance).
Else,
VkDevice or VkInstance, the allocator will use an
allocation scope of VK_SYSTEM_ALLOCATION_SCOPE_OBJECT.
The most specific allocator available is used (object, else device, else
instance).
Else,
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE.
Objects that are allocated from pools do not specify their own allocator. When an implementation requires host memory for such an object, that memory is sourced from the object’s parent pool’s allocator.
The application is not expected to handle allocating memory that is intended
for execution by the host due to the complexities of differing security
implementations across multiple platforms.
The implementation will allocate such memory internally and invoke an
application provided informational callback when these internal
allocations are allocated and freed.
Upon allocation of executable memory, pfnInternalAllocation will be
called.
Upon freeing executable memory, pfnInternalFree will be called.
An implementation will only call an informational callback for executable
memory allocations and frees.
The allocationType parameter to the pfnInternalAllocation and
pfnInternalFree functions may be one of the following values:
typedef enum VkInternalAllocationType {
VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0,
} VkInternalAllocationType;
VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE - 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
VkAllocationCallbacks structure between the time a vkCreate*
command returns and the time a corresponding vkDestroy* command
begins, that implementation must save a copy of the allocator before the
vkCreate* command returns.
The callback functions and any data structures they rely upon must remain
valid for the lifetime of the object they are associated with.
If an allocator is provided to a vkCreate* command, a compatible
allocator must be provided to the corresponding vkDestroy* command.
Two VkAllocationCallbacks structures are compatible if memory
allocated with pfnAllocation or pfnReallocation in each can be
freed with pfnReallocation or pfnFree in the other.
An allocator must not be provided to a vkDestroy* command if an
allocator was not provided to the corresponding vkCreate* command.
If a non-NULL allocator is used, the pfnAllocation,
pfnReallocation and pfnFree members must be non-NULL and
point to valid implementations of the callbacks.
An application can choose to not provide informational callbacks by setting
both pfnInternalAllocation and pfnInternalFree to NULL.
pfnInternalAllocation and pfnInternalFree must either both be
NULL or both be non-NULL.
If pfnAllocation or pfnReallocation fail, the implementation
may fail object creation and/or generate an
VK_ERROR_OUT_OF_HOST_MEMORY error, as appropriate.
Allocation callbacks must not call any Vulkan commands.
The following sets of rules define when an implementation is permitted to call the allocator callbacks.
pfnAllocation or pfnReallocation may be called in the following
situations:
VkDevice or VkInstance may be
allocated from any API command.
Allocations scoped to a VkPipelineCache may only be allocated
from:
vkCreatePipelineCache
vkMergePipelineCaches for dstCache
vkCreateGraphicsPipelines for pPipelineCache
vkCreateComputePipelines for pPipelineCache
Allocations scoped to a VkDescriptorPool may only be allocated
from:
vkAllocateDescriptorSets for the descriptorPool member of
its pAllocateInfo parameter
vkCreateDescriptorPool
Allocations scoped to a VkCommandPool may only be allocated from:
vkCreateCommandPool
vkAllocateCommandBuffers for the commandPool member of its
pAllocateInfo parameter
vkCmd* command whose commandBuffer was allocated from
that VkCommandPool
vkCreate* command.
pfnFree may be called in the following situations:
VkDevice or VkInstance may be freed
from any API command.
VkPipelineCache may be freed from
vkDestroyPipelineCache.
Allocations scoped to a VkDescriptorPool may be freed from
Allocations scoped to a VkCommandPool may be freed from:
vkResetCommandBuffer whose commandBuffer was allocated from
that VkCommandPool
vkDestroy* command.