More documentation. Especially added new section "Finding out if memory is mappable".
This commit is contained in:
parent
a3e019d476
commit
0c11b12574
6 changed files with 190 additions and 131 deletions
|
@ -353,17 +353,63 @@ Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA)
|
|||
currently provide `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` flag on all memory types that are
|
||||
`VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`, so on this platform you may not need to bother.
|
||||
|
||||
\section memory_mapping_finding_if_memory_mappable Finding out if memory is mappable
|
||||
|
||||
It may happen that your allocation ends up in memory that is `HOST_VISIBLE` (available for mapping)
|
||||
despite it wasn't explicitly requested.
|
||||
For example, application may work on integrated graphics with unified memory (like Intel) or
|
||||
allocation from video memory might have failed, so the library chose system memory as fallback.
|
||||
|
||||
You can detect this case and map such allocation to access its memory on CPU directly,
|
||||
instead of launching a transfer operation.
|
||||
You can even use `VMA_ALLOCATION_CREATE_MAPPED_BIT` flag while creating allocations
|
||||
that are not necessarily `HOST_VISIBLE` (e.g. using `VMA_MEMORY_USAGE_GPU_ONLY`).
|
||||
If the allocation ends up in memory type that is `HOST_VISIBLE`, it will be persistently mapped and you can use it directly.
|
||||
If not, the flag is just ignored.
|
||||
Example:
|
||||
|
||||
\code
|
||||
VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
bufCreateInfo.size = sizeof(ConstantBuffer);
|
||||
bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
|
||||
VmaAllocationCreateInfo allocCreateInfo = {};
|
||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
||||
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
|
||||
VkBuffer buf;
|
||||
VmaAllocation alloc;
|
||||
VmaAllocationInfo allocInfo;
|
||||
vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo);
|
||||
|
||||
if(allocInfo.pUserData != nullptr)
|
||||
{
|
||||
// Allocation ended up in mappable memory.
|
||||
// It's persistently mapped. You can access it directly.
|
||||
memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocation ended up in non-mappable memory.
|
||||
// You need to create CPU-side copy in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer.
|
||||
}
|
||||
\endcode
|
||||
|
||||
|
||||
\page custom_memory_pools Custom memory pools
|
||||
|
||||
The library automatically creates and manages default memory pool for each
|
||||
memory type available on the device. A pool contains a number of
|
||||
`VkDeviceMemory` blocks. You can create custom pool and allocate memory out of
|
||||
it. It can be useful if you want to:
|
||||
A memory pool contains a number of `VkDeviceMemory` blocks.
|
||||
The library automatically creates and manages default pool for each memory type available on the device.
|
||||
Default memory pool automatically grows in size.
|
||||
Size of allocated blocks is also variable and managed automatically.
|
||||
|
||||
You can create custom pool and allocate memory out of it.
|
||||
It can be useful if you want to:
|
||||
|
||||
- Keep certain kind of allocations separate from others.
|
||||
- Enforce particular size of Vulkan memory blocks.
|
||||
- Enforce particular, fixed size of Vulkan memory blocks.
|
||||
- Limit maximum amount of Vulkan memory allocated for that pool.
|
||||
- Reserve minimum or fixed amount of Vulkan memory always preallocated for that pool.
|
||||
|
||||
To use custom memory pools:
|
||||
|
||||
|
@ -375,7 +421,7 @@ To use custom memory pools:
|
|||
Example:
|
||||
|
||||
\code
|
||||
// Create a pool that could have at most 2 blocks, 128 MiB each.
|
||||
// Create a pool that can have at most 2 blocks, 128 MiB each.
|
||||
VmaPoolCreateInfo poolCreateInfo = {};
|
||||
poolCreateInfo.memoryTypeIndex = ...
|
||||
poolCreateInfo.blockSize = 128ull * 1024 * 1024;
|
||||
|
@ -1156,7 +1202,7 @@ typedef VkFlags VmaAllocationCreateFlags;
|
|||
|
||||
typedef struct VmaAllocationCreateInfo
|
||||
{
|
||||
/// Use VmaAllocationCreateFlagBits enum.
|
||||
/// Use #VmaAllocationCreateFlagBits enum.
|
||||
VmaAllocationCreateFlags flags;
|
||||
/** \brief Intended usage of memory.
|
||||
|
||||
|
@ -1612,16 +1658,22 @@ for(size_t i = 0; i < allocations.size(); ++i)
|
|||
}
|
||||
\endcode
|
||||
|
||||
Warning! This function is not correct according to Vulkan specification. Use it
|
||||
at your own risk. That's becuase Vulkan doesn't guarantee that memory
|
||||
Note: Please don't expect memory to be fully compacted after this call.
|
||||
Algorithms inside are based on some heuristics that try to maximize number of Vulkan
|
||||
memory blocks to make totally empty to release them, as well as to maximimze continuous
|
||||
empty space inside remaining blocks, while minimizing the number and size of data that
|
||||
needs to be moved. Some fragmentation still remains after this call. This is normal.
|
||||
|
||||
Warning: This function is not 100% correct according to Vulkan specification. Use it
|
||||
at your own risk. That's because Vulkan doesn't guarantee that memory
|
||||
requirements (size and alignment) for a new buffer or image are consistent. They
|
||||
may be different even for subsequent calls with the same parameters. It really
|
||||
does happen on some platforms, especially with images.
|
||||
|
||||
This function may be time-consuming, so you shouldn't call it too often (like
|
||||
every frame or after every resource creation/destruction), but rater you can
|
||||
call it on special occasions (like when reloading a game level, when you just
|
||||
destroyed a lot of objects).
|
||||
Warning: This function may be time-consuming, so you shouldn't call it too often
|
||||
(like every frame or after every resource creation/destruction).
|
||||
You can call it on special occasions (like when reloading a game level or
|
||||
when you just destroyed a lot of objects).
|
||||
*/
|
||||
VkResult vmaDefragment(
|
||||
VmaAllocator allocator,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue