Skip to content

Commit 27c84e2

Browse files
Merge remote-tracking branch 'origin/MemoryBudget' into MemoryBudget
# Conflicts: # src/vk_mem_alloc.h
2 parents 353e367 + bc95d25 commit 27c84e2

1 file changed

Lines changed: 79 additions & 12 deletions

File tree

src/vk_mem_alloc.h

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//
2-
//
32
// Copyright (c) 2017-2019 Advanced Micro Devices, Inc. All rights reserved.
43
//
54
// Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -30,9 +29,9 @@ extern "C" {
3029

3130
/** \mainpage Vulkan Memory Allocator
3231

33-
<b>Version 2.3.0-development</b> (2019-07-02)
32+
<b>Version 2.3.0-development</b> (2019-11-02)
3433

35-
Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved. \n
34+
Copyright (c) 2017-2019 Advanced Micro Devices, Inc. All rights reserved. \n
3635
License: MIT
3736

3837
Documentation of all members: vk_mem_alloc.h
@@ -55,6 +54,9 @@ Documentation of all members: vk_mem_alloc.h
5554
- [Persistently mapped memory](@ref memory_mapping_persistently_mapped_memory)
5655
- [Cache control](@ref memory_mapping_cache_control)
5756
- [Finding out if memory is mappable](@ref memory_mapping_finding_if_memory_mappable)
57+
- \subpage staying_within_budget
58+
- [Querying for budget](@ref staying_within_budget_querying_for_budget)
59+
- [Controlling memory usage](@ref staying_within_budget_controlling_memory_usage)
5860
- \subpage custom_memory_pools
5961
- [Choosing memory type index](@ref custom_memory_pools_MemTypeIndex)
6062
- [Linear allocation algorithm](@ref linear_algorithm)
@@ -524,6 +526,78 @@ else
524526
\endcode
525527

526528

529+
\page staying_within_budget Staying within budget
530+
531+
When developing a graphics-intensive game or program, it is important to avoid allocating
532+
more GPU memory than it's physically available. When the memory is over-committed,
533+
various bad things can happen, depending on the specific GPU, graphics driver, and
534+
operating system:
535+
536+
- It may just work without any problems.
537+
- The application may slow down because some memory blocks are moved to system RAM
538+
and the GPU has to access them through PCI Express bus.
539+
- A new allocation may take very long time to complete, even few seconds, and possibly
540+
freeze entire system.
541+
- The new allocation may fail with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
542+
- It may even result in GPU crash (TDR), observed as `VK_ERROR_DEVICE_LOST`
543+
returned somewhere later.
544+
545+
\section staying_within_budget_querying_for_budget Querying for budget
546+
547+
To query for current memory usage and available budget, use function vmaGetBudget().
548+
Returned structure #VmaBudget contains quantities expressed in bytes, per Vulkan memory heap.
549+
550+
Please note that this function returns different information and works faster than
551+
vmaCalculateStats(). vmaGetBudget() can be called every frame or even before every
552+
allocation, while vmaCalculateStats() is intended to be used rarely,
553+
only to obtain statistical information, e.g. for debugging purposes.
554+
555+
It is recommended to use <b>VK_EXT_memory_budget</b> device extension to obtain information
556+
about the budget from Vulkan device. VMA is able to use this extension automatically.
557+
When not enabled, the allocator behaves same way, but then it estimates current usage
558+
and available budget based on its internal information and Vulkan memory heap sizes,
559+
which may be less precise. In order to use this extension:
560+
561+
1. Make sure extensions VK_EXT_memory_budget and VK_KHR_get_physical_device_properties2
562+
required by it are available and enable them. Please note that the first is a device
563+
extension and the second is instance extension!
564+
2. Use flag #VMA_ALLOCATOR_CREATE_ ?? when creating #VmaAllocator object.
565+
3. Make sure to call vmaSetCurrentFrameIndex() every frame. Budget is queried from
566+
Vulkan inside of it to avoid overhead of querying it with every allocation.
567+
568+
\section staying_within_budget_controlling_memory_usage Controlling memory usage
569+
570+
There are many ways in which you can try to stay within the budget.
571+
572+
First, when making new allocation requires allocating a new memory block, the library
573+
tries not to exceed the budget automatically. If a block with default recommended size
574+
(e.g. 256 MB) would go over budget, a smaller block is allocated, possibly even
575+
dedicated memory for just this resource.
576+
577+
If the size of the requested resource plus current memory usage is more than the
578+
budget, by default the library still tries to create it, leaving it to the Vulkan
579+
implementation whether the allocation succeeds or fails. You can change this behavior
580+
by using #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag. With it, the allocation is
581+
not made if it would exceed the budget or if the budget is already exceeded.
582+
Some other allocations become lost instead to make room for it, if the mechanism of
583+
[lost allocations](@ref lost_allocations) is used.
584+
If that is not possible, the allocation fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
585+
Example usage pattern may be to pass the #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag
586+
when creating resources that are not essential for the application (e.g. the texture
587+
of a specific object) and not to pass it when creating critically important resources
588+
(e.g. render targets).
589+
590+
Finally, you can also use #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT flag to make sure
591+
a new allocation is created only when it fits inside one of the existing memory blocks.
592+
If it would require to allocate a new block, if fails instead with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
593+
This also ensures that the function call is very fast because it never goes to Vulkan
594+
to obtain a new block.
595+
596+
Please note that creating \ref custom_memory_pools with VmaPoolCreateInfo::minBlockCount
597+
set to more than 0 will try to allocate memory blocks without checking whether they
598+
fit within budget.
599+
600+
527601
\page custom_memory_pools Custom memory pools
528602

529603
A memory pool contains a number of `VkDeviceMemory` blocks.
@@ -2102,17 +2176,10 @@ typedef struct VmaBudget
21022176

21032177
It might be different (most probably smaller) than `VkMemoryHeap::size[heapIndex]` due to factors
21042178
external to the program, like other programs also consuming system resources.
2105-
21062179
Difference `budget - usage` is the amount of additional memory that can probably
2107-
be allocated without problems. Exceeding the budget may result, depending on operating
2108-
system and graphics driver:
2109-
2110-
- Allocation failing with `VK_ERROR_OUT_OF_DEVICE_MEMORY`.
2111-
- Allocation taking very long time, even few seconds.
2112-
- Overall system slowdown.
2113-
- Even GPU crash (TDR), observed as `VK_ERROR_DEVICE_LOST` returned somewhere later.
2180+
be allocated without problems. Exceeding the budget may result in various problems.
21142181
*/
2115-
VkDeviceSize budget;
2182+
VkDeviceSize budget[VK_MAX_MEMORY_HEAPS];
21162183
} VmaBudget;
21172184

21182185
/** \brief Retrieves information about current memory budget for all memory heaps.

0 commit comments

Comments
 (0)