From b0fce340b6c581d2bb75ca6c8c6e55235a52d8e2 Mon Sep 17 00:00:00 2001 From: Adam Sawicki Date: Thu, 29 Jul 2021 13:12:59 +0200 Subject: [PATCH] Fixes and improvements in documentation --- README.md | 1 + docs/html/allocation_annotation.html | 2 +- docs/html/choosing_memory_type.html | 2 +- docs/html/custom_memory_pools.html | 3 ++- docs/html/debugging_memory_usage.html | 2 +- docs/html/defragmentation.html | 6 +++--- docs/html/general_considerations.html | 2 +- docs/html/lost_allocations.html | 10 +++++----- docs/html/memory_mapping.html | 4 ++-- docs/html/opengl_interop.html | 4 ++-- docs/html/record_and_replay.html | 2 +- docs/html/staying_within_budget.html | 2 +- docs/html/vk__mem__alloc_8h.html | 6 +++--- docs/html/vk_khr_dedicated_allocation.html | 2 +- include/vk_mem_alloc.h | 6 ++++-- 15 files changed, 29 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index b1e2dba..e89e5b5 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ Additional features: - Convert this JSON dump into a picture to visualize your memory. See [tools/VmaDumpVis](tools/VmaDumpVis/README.md). - Debugging incorrect memory usage: Enable initialization of all allocated memory with a bit pattern to detect usage of uninitialized or freed memory. Enable validation of a magic number before and after every allocation to detect out-of-bounds memory corruption. - Record and replay sequence of calls to library functions to a file to check correctness, measure performance, and gather statistics. +- Support for interoperability with OpenGL. # Prequisites diff --git a/docs/html/allocation_annotation.html b/docs/html/allocation_annotation.html index 0c20818..9f39d7c 100644 --- a/docs/html/allocation_annotation.html +++ b/docs/html/allocation_annotation.html @@ -71,7 +71,7 @@ $(function() {

Allocation user data

-

You can annotate allocations with your own information, e.g. for debugging purposes. To do that, fill VmaAllocationCreateInfo::pUserData field when creating an allocation. It's an opaque void* pointer. You can use it e.g. as a pointer, some handle, index, key, ordinal number or any other value that would associate the allocation with your custom metadata.

+

You can annotate allocations with your own information, e.g. for debugging purposes. To do that, fill VmaAllocationCreateInfo::pUserData field when creating an allocation. It is an opaque void* pointer. You can use it e.g. as a pointer, some handle, index, key, ordinal number or any other value that would associate the allocation with your custom metadata.

VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
// Fill bufferInfo...
diff --git a/docs/html/choosing_memory_type.html b/docs/html/choosing_memory_type.html index 73a7dcd..93114b6 100644 --- a/docs/html/choosing_memory_type.html +++ b/docs/html/choosing_memory_type.html @@ -133,7 +133,7 @@ Custom memory pools

If you allocate from custom memory pool, all the ways of specifying memory requirements described above are not applicable and the aforementioned members of VmaAllocationCreateInfo structure are ignored. Memory type is selected explicitly when creating the pool and then used to make all the allocations from that pool. For further details, see Custom memory pools.

Dedicated allocations

-

Memory for allocations is reserved out of larger block of VkDeviceMemory allocated from Vulkan internally. That's the main feature of this whole library. You can still request a separate memory block to be created for an allocation, just like you would do in a trivial solution without using any allocator. In that case, a buffer or image is always bound to that memory at offset 0. This is called a "dedicated allocation". You can explicitly request it by using flag VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. The library can also internally decide to use dedicated allocation in some cases, e.g.:

+

Memory for allocations is reserved out of larger block of VkDeviceMemory allocated from Vulkan internally. That is the main feature of this whole library. You can still request a separate memory block to be created for an allocation, just like you would do in a trivial solution without using any allocator. In that case, a buffer or image is always bound to that memory at offset 0. This is called a "dedicated allocation". You can explicitly request it by using flag VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. The library can also internally decide to use dedicated allocation in some cases, e.g.:

  • When the size of the allocation is large.
  • When VK_KHR_dedicated_allocation extension is enabled and it reports that dedicated allocation is required or recommended for the resource.
  • diff --git a/docs/html/custom_memory_pools.html b/docs/html/custom_memory_pools.html index e3268ac..1165c9f 100644 --- a/docs/html/custom_memory_pools.html +++ b/docs/html/custom_memory_pools.html @@ -76,6 +76,7 @@ $(function() {
  • 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.
  • +
  • Use extra parameters for a set of your allocations that are available in VmaPoolCreateInfo but not in VmaAllocationCreateInfo - e.g., custom minimum alignment, custom pNext chain.

To use custom memory pools:

    @@ -181,7 +182,7 @@ Ring buffer

    Ring buffer is available only in pools with one memory block - VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined.

    Buddy allocation algorithm

    -

    There is another allocation algorithm that can be used with custom pools, called "buddy". Its internal data structure is based on a tree of blocks, each having size that is a power of two and a half of its parent's size. When you want to allocate memory of certain size, a free node in the tree is located. If it's too large, it is recursively split into two halves (called "buddies"). However, if requested allocation size is not a power of two, the size of a tree node is aligned up to the nearest power of two and the remaining space is wasted. When two buddy nodes become free, they are merged back into one larger node.

    +

    There is another allocation algorithm that can be used with custom pools, called "buddy". Its internal data structure is based on a tree of blocks, each having size that is a power of two and a half of its parent's size. When you want to allocate memory of certain size, a free node in the tree is located. If it is too large, it is recursively split into two halves (called "buddies"). However, if requested allocation size is not a power of two, the size of a tree node is aligned up to the nearest power of two and the remaining space is wasted. When two buddy nodes become free, they are merged back into one larger node.

    Buddy allocator

    The advantage of buddy allocation algorithm over default algorithm is faster allocation and deallocation, as well as smaller external fragmentation. The disadvantage is more wasted space (internal fragmentation).

    For more information, please read "Buddy memory allocation" on Wikipedia or other sources that describe this concept in general.

    diff --git a/docs/html/debugging_memory_usage.html b/docs/html/debugging_memory_usage.html index ce21667..b66e56f 100644 --- a/docs/html/debugging_memory_usage.html +++ b/docs/html/debugging_memory_usage.html @@ -99,7 +99,7 @@ Corruption detection
    #define VMA_DEBUG_DETECT_CORRUPTION 1
    #include "vk_mem_alloc.h"

When this feature is enabled, number of bytes specified as VMA_DEBUG_MARGIN (it must be multiply of 4) before and after every allocation is filled with a magic number. This idea is also know as "canary". Memory is automatically mapped and unmapped if necessary.

-

This number is validated automatically when the allocation is destroyed. If it's not equal to the expected value, VMA_ASSERT() is executed. It clearly means that either CPU or GPU overwritten the memory outside of boundaries of the allocation, which indicates a serious bug.

+

This number is validated automatically when the allocation is destroyed. If it is not equal to the expected value, VMA_ASSERT() is executed. It clearly means that either CPU or GPU overwritten the memory outside of boundaries of the allocation, which indicates a serious bug.

You can also explicitly request checking margins of all allocations in all memory blocks that belong to specified memory types by using function vmaCheckCorruption(), or in memory blocks that belong to specified custom pool, by using function vmaCheckPoolCorruption().

Margin validation (corruption detection) works only for memory types that are HOST_VISIBLE and HOST_COHERENT.

diff --git a/docs/html/defragmentation.html b/docs/html/defragmentation.html index 0f606b5..cfe3ac5 100644 --- a/docs/html/defragmentation.html +++ b/docs/html/defragmentation.html @@ -170,8 +170,8 @@ Defragmenting GPU memory
defragInfo.allocationCount = allocCount;
defragInfo.pAllocations = allocations.data();
defragInfo.pAllocationsChanged = allocationsChanged.data();
-
defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE; // Notice it's "GPU" this time.
-
defragInfo.maxGpuAllocationsToMove = UINT32_MAX; // Notice it's "GPU" this time.
+
defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE; // Notice it is "GPU" this time.
+
defragInfo.maxGpuAllocationsToMove = UINT32_MAX; // Notice it is "GPU" this time.
defragInfo.commandBuffer = commandBuffer;
VmaDefragmentationContext defragCtx;
@@ -224,7 +224,7 @@ Writing custom defragmentation algorithm

If you want to implement your own, custom defragmentation algorithm, there is infrastructure prepared for that, but it is not exposed through the library API - you need to hack its source code. Here are steps needed to do this:

  1. Main thing you need to do is to define your own class derived from base abstract class VmaDefragmentationAlgorithm and implement your version of its pure virtual methods. See definition and comments of this class for details.
  2. -
  3. Your code needs to interact with device memory block metadata. If you need more access to its data than it's provided by its public interface, declare your new class as a friend class e.g. in class VmaBlockMetadata_Generic.
  4. +
  5. Your code needs to interact with device memory block metadata. If you need more access to its data than it is provided by its public interface, declare your new class as a friend class e.g. in class VmaBlockMetadata_Generic.
  6. If you want to create a flag that would enable your algorithm or pass some additional flags to configure it, add them to VmaDefragmentationFlagBits and use them in VmaDefragmentationInfo2::flags.
  7. Modify function VmaBlockVectorDefragmentationContext::Begin to create object of your new class whenever needed.
diff --git a/docs/html/general_considerations.html b/docs/html/general_considerations.html index 9083b5e..4bd639f 100644 --- a/docs/html/general_considerations.html +++ b/docs/html/general_considerations.html @@ -112,7 +112,7 @@ Features not supported

Features deliberately excluded from the scope of this library: