10.2.1. CPU通路裝置記憶體對象
通過
vkAllocateMemory
建立的記憶體對象不能被CPU端直接通路。
建立時帶有
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
屬性的記憶體對象被認為是 可映射的 。 記憶體對象必須是可映射的,才能被映射到CPU端。
可調用如下指令可以擷取指向映射到可映射記憶體對象的指針:
VkResult vkMapMemory(
VkDevice device,
VkDeviceMemory memory,
VkDeviceSize offset,
VkDeviceSize size,
VkMemoryMapFlags flags,
void** ppData);
-
是擁有記憶體對象的邏輯裝置。device
-
是将要被映射的memory
對象。VkDeviceMemory
-
是一個從記憶體對象的起始的 從0開始的位元組offset。offset
-
是需要映射的記憶體區間的大小,或者值為size
時表示 從VK_WHOLE_SIZE
到配置設定的記憶體結尾的全部映射。offset
-
被保留。flags
-
指向一個 被傳回的 host-accessible指向 被映射的區間指針。 這個指針 減去ppData
必須被按照offset
::VkPhysicalDeviceLimits
對齊。minMemoryMapAlignment
若調用
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, 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 . |
vkMapMemory
并不在傳回一個host端可通路的指針之前檢查裝置記憶體目前是否正在使用中。 應用程式必須保證之前送出的任何指令(會向該區間寫入的指令)已經在host端讀取或者寫入完成,且任何之前被送出的指令(從該區間讀取内容的指令) 在host端寫入之前已經完成。 (參看 這裡 擷取更詳細的資訊). 若配置設定裝置記憶體時未帶有
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
标志位,必須提供這些保證,應用程式必須從 區間的起始到最鄰近的多個
VkPhysicalDeviceLimits
::
nonCoherentAtomSize
聚集在一起,保證從區間的尾部到最鄰近的多個
VkPhysicalDeviceLimits
::
nonCoherentAtomSize
聚集在一起。
當一塊區域的裝置記憶體被映射到主機端可通路,應用程式需要負責同步該區間的記憶體通路。
注意 應用程式開發者需要對本章Synchronization and Cache Control 描述的機制相當熟悉, 這對于維持按序通路記憶體來說極其重要。 |
正确使用
-
必須未被映射過memory
-
必須要被offset
的大小要小memory
- 若
不等于size
,VK_WHOLE_SIZE
必須大于size
- 若
不等于size
,VK_WHOLE_SIZE
必須小于等于size
減去memory
的結果的大小offset
-
必須在建立時帶有 記憶體類型memory
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
Valid Usage (Implicit)
-
must be a validdevice
handleVkDevice
-
must be a validmemory
handleVkDeviceMemory
-
must beflags
-
must be a pointer to a pointerppData
-
must have been created, allocated, or retrieved frommemory
device
Host Synchronization
- Host access to
must be externally synchronizedmemory
Return Codes
Success
-
VK_SUCCESS
Failure
-
VK_ERROR_OUT_OF_HOST_MEMORY
-
VK_ERROR_OUT_OF_DEVICE_MEMORY
-
VK_ERROR_MEMORY_MAP_FAILED
為了應用程式可以與非一緻性記憶體配置設定一起工作,有兩個指令可以使用:
vkFlushMappedMemoryRanges
和
vkInvalidateMappedMemoryRanges
。
注意 若建立記憶體對象時帶有 參數, 和 是沒有必要的,且可能會有性能損失。 |
可調用如下指令來把CPU緩存重新整理到非一緻的記憶體區域中:
VkResult vkFlushMappedMemoryRanges(
VkDevice device,
uint32_t memoryRangeCount,
const VkMappedMemoryRange* pMemoryRanges);
-
是擁有記憶體對象的邏輯裝置。device
-
是memoryRangeCount
數組的長度。pMemoryRanges
-
是一個指向pMemoryRanges
類型數組的指針,描述了需要重新整理的記憶體區域。VkMappedMemoryRange
vkFlushMappedMemoryRanges
必須用于保證host端寫入到非一緻性記憶體的内容對于 device可見。 隻能在host端寫入到非一緻性記憶體之後,且在會讀取或寫入這些記憶體的指令緩沖區被送出到隊列之前,才可以被調用。
注意 取消非一緻性記憶體映射并不意味着重新整理被映射的記憶體, 沒有被重新整理的 host端寫入的内容 可能對device不可見。 |
Valid Usage (Implicit)
-
must be a validdevice
handleVkDevice
-
must be a pointer to an array ofpMemoryRanges
validmemoryRangeCount
structuresVkMappedMemoryRange
-
must be greater thanmemoryRangeCount
Return Codes
Success
-
VK_SUCCESS
Failure
-
VK_ERROR_OUT_OF_HOST_MEMORY
-
VK_ERROR_OUT_OF_DEVICE_MEMORY
可調用如下函數從host端cache使 非一緻性記憶體無效:
VkResult vkInvalidateMappedMemoryRanges(
VkDevice device,
uint32_t memoryRangeCount,
const VkMappedMemoryRange* pMemoryRanges);
-
是擁有記憶體範圍的邏輯裝置。device
-
是memoryRangeCount
數組的長度。pMemoryRanges
-
是一個指針,指向一個pMemoryRanges
資料結構的數組,描述了需要無效化的記憶體區間。VkMappedMemoryRange
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.
注意 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. |
Valid Usage (Implicit)
-
must be a validdevice
handleVkDevice
-
must be a pointer to an array ofpMemoryRanges
validmemoryRangeCount
structuresVkMappedMemoryRange
-
must be greater thanmemoryRangeCount
Return Codes
Success
-
VK_SUCCESS
Failure
-
VK_ERROR_OUT_OF_HOST_MEMORY
-
VK_ERROR_OUT_OF_DEVICE_MEMORY
VkMappedMemoryRange
類型資料結構定義如下:
typedef struct VkMappedMemoryRange {
VkStructureType sType;
const void* pNext;
VkDeviceMemory memory;
VkDeviceSize offset;
VkDeviceSize size;
} VkMappedMemoryRange;
-
是資料結構的類型。sType
-
是pNext
或者一個指向拓展特定的資料結構的指針。NULL
-
是這個區間所在的記憶體對象。memory
-
是一個從記憶體對象的起始位置開始的,從0開始的偏移量。offset
-
要麼是區間的大小,要麼是 影響到 從size
到目前映射到配置設定的記憶體結束的區間的offset
。VK_WHOLE_SIZE
正确使用
-
目前必須已經被映射了memory
- 若
和size
不相等,VK_WHOLE_SIZE
和offset
必須: 指定已經映射的記憶體size
之中的一段區間。memory
- 若
和size
相等,VK_WHOLE_SIZE
必須: 和已經映射的記憶體的區間完全相同。offset
-
必須: 是offset
::VkPhysicalDeviceLimits
的倍數nonCoherentAtomSize
- 若
和size
不相等,VK_WHOLE_SIZE
必須: 是size
::VkPhysicalDeviceLimits
的倍數。nonCoherentAtomSize
Valid Usage (Implicit)
-
must besType
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE
-
must bepNext
NULL
-
must be a validmemory
handleVkDeviceMemory
editing-note TODO (Tobias) - There’s a circular section reference between this next section and the 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. |
Host-visible memory types that advertise the
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
property still require 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
VK_ACCESS_HOST_WRITE_BIT
and
VK_PIPELINE_STAGE_HOST_BIT
to a destination of the relevant device pipeline stages and access types must be performed. Note that such a barrier is performed 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.
應用程式若不在需要從host端通路記憶體對象,可調用如下指令來取消映射:
void vkUnmapMemory(
VkDevice device,
VkDeviceMemory memory);
-
是擁有記憶體的邏輯裝置。device
-
是将要被取消映射的記憶體對象。memory
正确使用
-
在目前必須被映射過memory
Valid Usage (Implicit)
-
must be a validdevice
handleVkDevice
-
must be a validmemory
handleVkDeviceMemory
-
must have been created, allocated, or retrieved frommemory
device
Host Synchronization
- Host access to
must be externally synchronizedmemory