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.