1151 lines
48 KiB
Plaintext
1151 lines
48 KiB
Plaintext
// 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
|
|
****
|
|
* pname:pfnAllocation must: be a pointer to a valid user-defined
|
|
tlink:PFN_vkAllocationFunction
|
|
* pname:pfnReallocation must: be a pointer to a valid user-defined
|
|
tlink:PFN_vkReallocationFunction
|
|
* pname:pfnFree must: be a pointer to a valid user-defined
|
|
tlink:PFN_vkFreeFunction
|
|
* 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 <<memory-host-allocation-scope,here>>.
|
|
|
|
[[vkAllocationFunction_return_rules]]
|
|
If pname:pfnAllocation is unable to allocate the requested memory, it must:
|
|
return `NULL`.
|
|
If the allocation was successful, it must: return a valid pointer to memory
|
|
allocation containing at least pname:size bytes, and with the pointer value
|
|
being a multiple of pname:alignment.
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
Correct Vulkan operation cannot: be assumed if the application does not
|
|
follow these rules.
|
|
|
|
For example, pname:pfnAllocation (or pname:pfnReallocation) could cause
|
|
termination of running Vulkan instance(s) on a failed allocation for
|
|
debugging purposes, either directly or indirectly.
|
|
In these circumstances, it cannot: be assumed that any part of any affected
|
|
VkInstance objects are going to operate correctly (even
|
|
flink:vkDestroyInstance), and the application must: ensure it cleans up
|
|
properly via other means (e.g. process termination).
|
|
====
|
|
|
|
If pname:pfnAllocation returns `NULL`, and if the implementation is unable
|
|
to continue correct processing of the current command without the requested
|
|
allocation, it must: treat this as a run-time error, and generate
|
|
ename:VK_ERROR_OUT_OF_HOST_MEMORY at the appropriate time for the command in
|
|
which the condition was detected, as described in <<fundamentals-errorcodes,
|
|
Return Codes>>.
|
|
|
|
If the implementation is able to continue correct processing of the current
|
|
command without the requested allocation, then it may: do so, and must: not
|
|
generate ename:VK_ERROR_OUT_OF_HOST_MEMORY as a result of this failed
|
|
allocation.
|
|
|
|
// 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 <<memory-host-allocation-scope,here>>.
|
|
|
|
pname:pfnReallocation must: return an allocation with enough space for
|
|
pname:size bytes, and the contents of the original allocation from bytes
|
|
zero to [eq]#min(original size, new size) - 1# must: be preserved in the
|
|
returned allocation.
|
|
If pname:size is larger than the old size, the contents of the additional
|
|
space are undefined.
|
|
If satisfying these requirements involves creating a new allocation, then
|
|
the old allocation should: be freed.
|
|
|
|
If pname:pOriginal is `NULL`, then pname:pfnReallocation must: behave
|
|
equivalently to a call to tlink:PFN_vkAllocationFunction with the same
|
|
parameter values (without pname:pOriginal).
|
|
|
|
If pname:size is zero, then pname:pfnReallocation must: behave equivalently
|
|
to a call to tlink:PFN_vkFreeFunction with the same pname:pUserData
|
|
parameter value, and pname:pMemory equal to pname:pOriginal.
|
|
|
|
If pname:pOriginal is non-`NULL`, the implementation must: ensure that
|
|
pname:alignment is equal to the pname:alignment used to originally allocate
|
|
pname:pOriginal.
|
|
|
|
If this function fails and pname:pOriginal is non-`NULL` the application
|
|
must: not free the old allocation.
|
|
|
|
pname:pfnReallocation must: follow the same
|
|
<<vkAllocationFunction_return_rules, rules for return values as
|
|
tname:PFN_vkAllocationFunction>>.
|
|
|
|
// 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 the requested type of an allocation.
|
|
* pname:allocationScope is a elink:VkSystemAllocationScope value
|
|
specifying the allocation scope of the lifetime of the allocation, as
|
|
described <<memory-host-allocation-scope,here>>.
|
|
|
|
This is a purely informational callback.
|
|
|
|
// 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 the requested type of an allocation.
|
|
* pname:allocationScope is a elink:VkSystemAllocationScope value
|
|
specifying the allocation scope of the lifetime of the allocation, as
|
|
described <<memory-host-allocation-scope,here>>.
|
|
|
|
// 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.
|
|
The allocation scope is provided in the pname:allocationScope parameter
|
|
passed to callbacks defined in slink:VkAllocationCallbacks.
|
|
Possible values for this parameter are defined by
|
|
elink:VkSystemAllocationScope:
|
|
|
|
include::../api/enums/VkSystemAllocationScope.txt[]
|
|
|
|
* ename:VK_SYSTEM_ALLOCATION_SCOPE_COMMAND - The allocation is scoped to
|
|
the duration of the Vulkan command.
|
|
* ename:VK_SYSTEM_ALLOCATION_SCOPE_OBJECT - The allocation is scoped to
|
|
the lifetime of the Vulkan object that is being created or used.
|
|
* ename:VK_SYSTEM_ALLOCATION_SCOPE_CACHE - The allocation is scoped to the
|
|
lifetime of a sname:VkPipelineCache object.
|
|
* ename:VK_SYSTEM_ALLOCATION_SCOPE_DEVICE - The allocation is scoped to
|
|
the lifetime of the Vulkan device.
|
|
* ename: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
|
|
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 - 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,{basebackend@docbook:c++:cpp}]
|
|
---------------------------------------------------
|
|
// 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 via chained 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 attribute flags for the heap.
|
|
The bits specified in pname:flags are:
|
|
+
|
|
--
|
|
// refBegin VkMemoryHeapFlagBits Bitmask specifying attribute flags for a heap
|
|
include::../api/enums/VkMemoryHeapFlagBits.txt[]
|
|
--
|
|
** if pname:flags contains ename:VK_MEMORY_HEAP_DEVICE_LOCAL_BIT, it means
|
|
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.
|
|
|
|
include::../validity/structs/VkMemoryHeap.txt[]
|
|
|
|
// 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 properties for this memory type.
|
|
The bits specified in pname:propertyFlags are:
|
|
+
|
|
--
|
|
// refBegin VkMemoryPropertyFlagBits Bitmask specifying properties for a memory type
|
|
include::../api/enums/VkMemoryPropertyFlagBits.txt[]
|
|
--
|
|
** if pname:propertyFlags has the
|
|
ename:VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT bit set, 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.
|
|
** if pname:propertyFlags has the
|
|
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT bit set, memory allocated
|
|
with this type can: be mapped for host access using flink:vkMapMemory.
|
|
** if pname:propertyFlags has the
|
|
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT bit set, host cache
|
|
management commands fname:vkFlushMappedMemoryRanges and
|
|
fname:vkInvalidateMappedMemoryRanges are not needed to make host writes
|
|
visible to the device or device writes visible to the host,
|
|
respectively.
|
|
** if pname:propertyFlags has the ename:VK_MEMORY_PROPERTY_HOST_CACHED_BIT
|
|
bit set, 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.
|
|
** if pname:propertyFlags has the
|
|
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set, the memory type
|
|
only allows device access to the memory.
|
|
Memory types must: not have both
|
|
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT and
|
|
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT set.
|
|
Additionally, the object's backing memory may: be provided by the
|
|
implementation lazily as specified in <<memory-device-lazy_allocation,
|
|
Lazily Allocated Memory>>.
|
|
|
|
include::../validity/structs/VkMemoryType.txt[]
|
|
|
|
// 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
|
|
<<memory-allocation, Memory Allocation>> chapter.
|
|
* pname:pMemory is a pointer to a sname:VkDeviceMemory handle in which
|
|
information about the allocated memory is returned.
|
|
|
|
Allocations returned by fname:vkAllocateMemory are guaranteed to meet any
|
|
alignment requirement 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
|
|
<<features-limits-maxMemoryAllocationCount,pname:maxMemoryAllocationCount>>
|
|
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
|
|
****
|
|
* 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.
|
|
|
|
.Valid Usage
|
|
****
|
|
* 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
|
|
* pname:allocationSize must: be greater than `0`
|
|
****
|
|
|
|
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
|
|
****
|
|
* At least one of pname:image and pname:buffer must: be
|
|
sname:VK_NULL_HANDLE
|
|
* 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
|
|
* 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
|
|
* If pname:image is not sname:VK_NULL_HANDLE,
|
|
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
|
|
sname:VkMemoryRequirements::pname:size of the image
|
|
* If pname:buffer is not sname:VK_NULL_HANDLE,
|
|
sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the
|
|
sname:VkMemoryRequirements::pname:size of the buffer
|
|
****
|
|
|
|
include::../validity/structs/VkDedicatedAllocationMemoryAllocateInfoNV.txt[]
|
|
|
|
endif::VK_NV_dedicated_allocation[]
|
|
|
|
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[]
|
|
|
|
// 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
|
|
<<memory-allocation, Memory Allocation>> chapter.
|
|
|
|
Before freeing a memory object, an application must: ensure the memory
|
|
object is no longer in use by the device--for example by command buffers
|
|
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 <<resources-association, Resource Memory Association>> section.
|
|
|
|
If a memory object is mapped at the time it is freed, it is implicitly
|
|
unmapped.
|
|
|
|
.Valid Usage
|
|
****
|
|
* 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 VK_ERROR_MEMORY_MAP_FAILED.
|
|
The application can: improve the likelihood of success by reducing the size
|
|
of the mapped range and/or removing unneeded mappings using
|
|
fname:VkUnmapMemory.
|
|
====
|
|
|
|
[[memory-device-hostaccess-hazards]]
|
|
fname:vkMapMemory does not check whether the device memory is currently in
|
|
use before returning the host-accessible pointer.
|
|
The application must: guarantee that any previously submitted command that
|
|
writes to this range has completed before the host reads from or writes to
|
|
that range, and that any previously submitted command that reads from that
|
|
range has completed before the host writes to that region (see
|
|
<<synchronization-submission-host-writes, here>> for details on fulfilling
|
|
such a guarantee).
|
|
If the device memory was allocated without the
|
|
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT set, these guarantees must: be
|
|
made for an extended range: the application must: round down the start of
|
|
the range to the nearest multiple of
|
|
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
|
|
<<synchronization, Synchronization and Cache Control>> as they are crucial
|
|
to maintaining memory access ordering.
|
|
====
|
|
|
|
.Valid Usage
|
|
****
|
|
* pname:memory must: not currently be mapped
|
|
* pname:offset must: be less than the size of pname:memory
|
|
* If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be
|
|
greater than `0`
|
|
* 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
|
|
* pname:memory must: have been created with a memory type that reports
|
|
ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
|
****
|
|
|
|
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 performance cost.
|
|
====
|
|
|
|
// 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 must: be used to guarantee that host writes
|
|
to non-coherent memory are visible to the device.
|
|
It must: be called after the host writes to non-coherent memory have
|
|
completed and before command buffers that will read or write any of those
|
|
memory locations are submitted to a queue.
|
|
|
|
[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 must: be used to guarantee that device
|
|
writes to non-coherent memory are visible to the host.
|
|
It must: be called after command buffers that execute and flush (via memory
|
|
barriers) the device writes have completed, and before the host will read or
|
|
write any of those locations.
|
|
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
|
|
****
|
|
* pname:memory must: currently be mapped
|
|
* 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
|
|
* If pname:size is equal to ename:VK_WHOLE_SIZE, pname:offset must: be
|
|
within the currently mapped range of pname:memory
|
|
* pname:offset must: be a multiple of
|
|
sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize
|
|
* If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be a
|
|
multiple of sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize
|
|
****
|
|
|
|
include::../validity/structs/VkMappedMemoryRange.txt[]
|
|
|
|
ifdef::editing-notes[]
|
|
[NOTE]
|
|
.editing-note
|
|
====
|
|
TODO (Tobias) - There's a circular section reference between this next
|
|
section and the <<synchronization-fences-waiting,synchronization section>>.
|
|
The information is all covered by both places, but it seems a bit weird to
|
|
have them reference each other.
|
|
Not sure how to resolve it.
|
|
====
|
|
endif::editing-notes[]
|
|
|
|
Host-visible memory types that advertise the
|
|
ename:VK_MEMORY_PROPERTY_HOST_COHERENT_BIT property still require
|
|
<<synchronization-pipeline-barriers,memory barriers>> between host and
|
|
device in order to be coherent, but do not require additional cache
|
|
management operations to achieve coherency.
|
|
For host writes to be seen by subsequent command buffer operations, a
|
|
pipeline barrier from a source of ename:VK_ACCESS_HOST_WRITE_BIT and
|
|
ename:VK_PIPELINE_STAGE_HOST_BIT to a destination of the relevant device
|
|
<<synchronization-pipeline-stages, pipeline stages>> and
|
|
<<synchronization-access-types, access types>> must: be performed.
|
|
Note that such a barrier is performed
|
|
<<synchronization-submission-host-writes,implicitly>> upon each command
|
|
buffer submission, so an explicit barrier is only rarely needed (e.g. if a
|
|
command buffer waits upon an event signaled by the host, where the host
|
|
wrote some data after submission).
|
|
A pipeline barrier is required: to make writes visible to subsequent reads
|
|
on the host.
|
|
|
|
// 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
|
|
****
|
|
* 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
|
|
****
|
|
* pname:memory must: have been created with a memory type that reports
|
|
ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
|
|
****
|
|
|
|
include::../validity/protos/vkGetDeviceMemoryCommitment.txt[]
|
|
|