<divclass="textblock"><p>If you need to map memory on host, it may happen that two allocations are assigned to the same <code>VkDeviceMemory</code> block, so if you map them both at the same time, it will cause error because mapping single memory block multiple times is illegal in Vulkan.</p>
<p>It is safer, more convenient and more efficient to use special feature designed for that: persistently mapped memory. Allocations made with <code>VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</code> flag set in <aclass="el"href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b"title="Use VmaAllocationCreateFlagBits enum. ">VmaAllocationCreateInfo::flags</a> are returned from device memory blocks that stay mapped all the time, so you can just access CPU pointer to it. <aclass="el"href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2"title="Pointer to the beginning of this allocation as mapped data. Null if this alloaction is not persistent...">VmaAllocationInfo::pMappedData</a> pointer is already offseted to the beginning of particular allocation. Example:</p>
<divclass="fragment"><divclass="line">VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };</div><divclass="line">bufCreateInfo.size = 1024;</div><divclass="line">bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;</div><divclass="line"></div><divclass="line"><aclass="code"href="struct_vma_allocation_create_info.html">VmaAllocationCreateInfo</a> allocCreateInfo = {};</div><divclass="line">allocCreateInfo.<aclass="code"href="struct_vma_allocation_create_info.html#accb8b06b1f677d858cb9af20705fa910">usage</a> = <aclass="code"href="vk__mem__alloc_8h.html#aa5846affa1e9da3800e3e78fae2305cca40bdf4cddeffeb12f43d45ca1286e0a5">VMA_MEMORY_USAGE_CPU_ONLY</a>;</div><divclass="line">allocCreateInfo.<aclass="code"href="struct_vma_allocation_create_info.html#add09658ac14fe290ace25470ddd6d41b">flags</a> = <aclass="code"href="vk__mem__alloc_8h.html#ad9889c10c798b040d59c92f257cae597ae443691ef3d077c0dc3de5576ac4c312">VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT</a>;</div><divclass="line"></div><divclass="line">VkBuffer buf;</div><divclass="line">VmaAllocation alloc;</div><divclass="line"><aclass="code"href="struct_vma_allocation_info.html">VmaAllocationInfo</a> allocInfo;</div><divclass="line"><aclass="code"href="vk__mem__alloc_8h.html#ac72ee55598617e8eecca384e746bab51">vmaCreateBuffer</a>(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);</div><divclass="line"></div><divclass="line"><spanclass="comment">// Buffer is immediately mapped. You can access its memory.</span></div><divclass="line">memcpy(allocInfo.<aclass="code"href="struct_vma_allocation_info.html#a5eeffbe2d2f30f53370ff14aefbadbe2">pMappedData</a>, myData, 1024);</div></div><!-- fragment --><p>Memory in Vulkan doesn't need to be unmapped before using it e.g. for transfers, but if you are not sure whether it's <code>HOST_COHERENT</code> (here is surely is because it's created with <code>VMA_MEMORY_USAGE_CPU_ONLY</code>), you should check it. If it's not, you should call <code>vkInvalidateMappedMemoryRanges()</code> before reading and <code>vkFlushMappedMemoryRanges()</code> after writing to mapped memory on CPU. Example:</p>
<divclass="fragment"><divclass="line">VkMemoryPropertyFlags memFlags;</div><divclass="line"><aclass="code"href="vk__mem__alloc_8h.html#a8701444752eb5de4464adb5a2b514bca">vmaGetMemoryTypeProperties</a>(allocator, allocInfo.<aclass="code"href="struct_vma_allocation_info.html#a7f6b0aa58c135e488e6b40a388dad9d5">memoryType</a>, &memFlags);</div><divclass="line"><spanclass="keywordflow">if</span>((memFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0)</div><divclass="line">{</div><divclass="line"> VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE };</div><divclass="line"> memRange.memory = allocInfo.<aclass="code"href="struct_vma_allocation_info.html#ae0bfb7dfdf79a76ffefc9a94677a2f67">deviceMemory</a>;</div><divclass="line"> memRange.offset = allocInfo.<aclass="code"href="struct_vma_allocation_info.html#a4a3c732388dbdc7a23f9365b00825268">offset</a>;</div><divclass="line"> memRange.size = allocInfo.<aclass="code"href="struct_vma_allocation_info.html#aac76d113a6a5ccbb09fea00fb25fd18f">size</a>;</div><divclass="line"> vkFlushMappedMemoryRanges(device, 1, &memRange);</div><divclass="line">}</div></div><!-- fragment --><p>On AMD GPUs on Windows, Vulkan memory from the type that has both <code>DEVICE_LOCAL</code> and <code>HOST_VISIBLE</code> flags should not be mapped for the time of any call to <code>vkQueueSubmit()</code> or <code>vkQueuePresent()</code>. Although legal, that would cause performance degradation because WDDM migrates such memory to system RAM. To ensure this, you can unmap all persistently mapped memory using just one function call. For details, see function <aclass="el"href="vk__mem__alloc_8h.html#a26b87244491c1fe77f11fe9ab5779c27"title="Unmaps persistently mapped memory of types that are HOST_COHERENT and DEVICE_LOCAL. ">vmaUnmapPersistentlyMappedMemory()</a>, <aclass="el"href="vk__mem__alloc_8h.html#a03366170bb8e186605518d2f5d65b85a"title="Maps back persistently mapped memory of types that are HOST_COHERENT and DEVICE_LOCAL. ">vmaMapPersistentlyMappedMemory()</a>. </p>