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 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 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(\textrm{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 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 scope of the lifetime of the allocation, as described
here.
Each allocation has a scope which defines its lifetime and which object it
is associated with. The 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 a 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 scope available:
VK_SYSTEM_ALLOCATION_SCOPE_COMMAND
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
scope. The most specific
allocator available is used (pipeline cache, else device, else
instance). Else,
VkDevice
or VkInstance
, the allocator will use a scope
of VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
. The most specific allocator
available is used (object, else device, else instance). Else,
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE
. The most
specific allocator available is used (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 from within the scope 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 created
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.
Host memory scoped to the lifetime of a VkPipelineCache
may only
be allocated from:
vkCreatePipelineCache
vkMergePipelineCaches
for dstCache
vkCreateGraphicsPipelines
for pPipelineCache
vkCreateComputePipelines
for pPipelineCache
Host memory scoped to the lifetime of a VkDescriptorPool
may only
be allocated from:
vkAllocateDescriptorSets
for the descriptorPool
member of
its pAllocateInfo
parameter
vkCreateDescriptorPool
Host memory scoped to the lifetime of a VkCommandPool
may only be
allocated from:
vkCreateCommandPool
vkAllocateCommandBuffers
for the commandPool
member of its
pAllocateInfo
parameter
vkCmd*
command whose commandBuffer
was created 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
.
Host memory scoped to the lifetime of a VkDescriptorPool
may be
freed from
Host memory scoped to the lifetime of a VkCommandPool
may be
freed from:
vkResetCommandBuffer
whose commandBuffer
was created from
that VkCommandPool
vkDestroy*
command.